> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fallow.tools/llms.txt
> Use this file to discover all available pages before exploring further.

# Non-JS file types

> Fallow analyzes HTML, Vue, Svelte, Astro, MDX, GraphQL, CSS modules, SCSS, and React Native files automatically. No plugins or config needed.

Fallow analyzes more than `.js` and `.ts` files. It extracts imports and exports from non-JavaScript file types automatically based on their extension. No plugins or config needed.

<Tabs>
  <Tab title="HTML">
    Fallow discovers `.html` files and extracts edges from `<script src>` and `<link>` tags. This is especially useful for projects that use HTML entry points (such as Parcel or vanilla setups).

    **What's supported:**

    * `<script src="./main.js">` script references
    * `<link rel="stylesheet" href="./styles.css">` stylesheet references
    * `<link rel="modulepreload" href="./vendor.js">` module preload references
    * Root-relative paths (e.g., `<script src="/src/main.tsx">`) are resolved against the project root, matching the convention used by Vite, Parcel, and similar dev servers. Root-relative resolution also applies when the reference comes from a JSX/TSX/JS/TS source file (see the JSX templates tab).

    ```html index.html theme={null}
    <!DOCTYPE html>
    <html>
      <head>
        <link rel="stylesheet" href="./styles/main.css" />
        <link rel="modulepreload" href="./vendor/lodash.js" />
      </head>
      <body>
        <div id="app"></div>
        <script src="./src/main.ts"></script>
      </body>
    </html>
    ```

    Fallow sees this file as referencing `./styles/main.css`, `./vendor/lodash.js`, and `./src/main.ts`.

    <Tip>
      The Parcel plugin automatically adds `index.html` as an entry pattern, so HTML entry files are picked up without any extra config.
    </Tip>

    **Angular template complexity.** Standalone `.html` files referenced via `templateUrl` and inline `@Component({ template: \`...\` })`literals both contribute synthetic`\<template>`complexity findings to`fallow health`. The scanner recognises control-flow blocks (`@if`, `@for`, `@switch`, `@case`, `@defer (when ...)`, `@let`), legacy structural directives (`\*ngIf`, `\*ngFor`), bound attributes (`\[x]`, `(x)`, `bind-x`, `on-x`), and `{{ }}`interpolations. Inline-template findings anchor at the`@Component`decorator line and suppress with`// fallow-ignore-next-line complexity`directly above the decorator; external-template findings suppress with`\<!-- fallow-ignore-file complexity -->`at the top of the`.html\` file.
  </Tab>

  <Tab title="Vue / Svelte">
    Fallow extracts the `<script>` block from Vue and Svelte single-file components and analyzes it like a standalone JS/TS module. It also scans `<template>` sections for component references, directives, and expression usage, so imports used only in templates are correctly tracked.

    **Script extraction:**

    * `<script>` and `<script setup>` blocks
    * `lang="ts"` and `lang="tsx"` attributes
    * `<script src="./external.ts">` external script references
    * HTML comments (`<!-- ... -->`) are filtered out before parsing

    **Vue template tracking:**

    * Component tags: `<MyComponent>` resolves to imported `MyComponent`
    * Custom directives: `v-focus-trap` resolves to imported `vFocusTrap`
    * `v-on` and `v-bind` object syntax (e.g., `v-on="handlers"`)
    * Template expressions: `{{ formatDate() }}` marks `formatDate` as used
    * Namespace member access: `utils.formatDate` in templates tracks the member usage

    **Svelte template tracking:**

    * Component tags: `<Button>` resolves to imported `Button`
    * Directives: `use:tooltip`, `transition:fade`, `animate:flip`, `in:fly`, `out:fade`
    * Attribute expressions: `{expression}` and shorthand attributes `{variable}`
    * `$store` subscriptions: `$myStore` marks `myStore` as used

    ```vue Example.vue theme={null}
    <script setup lang="ts">
    import { ref } from 'vue'
    import { formatDate } from '@/utils/date'
    import FocusTrap from '@/components/FocusTrap.vue'

    const count = ref(0)
    </script>

    <template>
      <FocusTrap>
        <div>{{ formatDate(new Date()) }}</div>
      </FocusTrap>
    </template>
    ```

    Fallow sees this file as importing `ref` from `vue`, `formatDate` from `@/utils/date`, and `FocusTrap` from `@/components/FocusTrap.vue`. The `<FocusTrap>` tag and `formatDate` reference in the template are tracked, so they won't be reported as unused even though they don't appear in the script block.

    <Warning>
      Svelte components export props implicitly. Fallow cannot distinguish between props and utility exports, which may cause false negatives for unused exports in `.svelte` files. See [Limitations](/analysis/limitations) for details.
    </Warning>
  </Tab>

  <Tab title="SSR layouts">
    SSR frameworks like [Hono](https://hono.dev) render HTML from layout components using either JSX or a tagged template literal (`` html`...` ``). Fallow treats `<script src="...">` and `<link rel="stylesheet|modulepreload" href="...">` inside both forms the same way it treats them in plain HTML: as asset references that keep the target file reachable.

    **What's supported:**

    * `<script src="./app.js">` inside JSX/TSX layouts and `` html`...` `` tagged templates
    * `<link rel="stylesheet" href="./global.css">` inside JSX/TSX layouts and `` html`...` `` tagged templates
    * `<link rel="modulepreload" href="./vendor.js">` inside JSX/TSX layouts and `` html`...` `` tagged templates
    * Root-relative paths (`<link href="/static/style.css">`) resolve against the source file's parent directory first, then the project root, matching how Vite/Parcel/Hono serve static assets

    ```tsx Layout.tsx theme={null}
    export const Layout = () => (
      <html>
        <head>
          <link rel="stylesheet" href="/static/style.css" />
          <script src="/static/app.js"></script>
        </head>
        <body>
          <h1>Hello from Hono</h1>
        </body>
      </html>
    );
    ```

    ```ts layout.ts theme={null}
    import { html } from 'hono/html'

    export const Layout = ({ title, body }: { title: string; body: string }) => html`
      <!doctype html>
      <html>
        <head>
          <title>${title}</title>
          <link rel="stylesheet" href="/static/style.css" />
          <script defer src="/static/app.js"></script>
        </head>
        <body>${body}</body>
      </html>
    `
    ```

    Fallow sees both files as referencing `/static/style.css` and `/static/app.js`, so sibling files in `static/` are correctly marked reachable.

    <Note>
      In JSX, only lowercase intrinsic elements (`<script>`, `<link>`) and plain string literals (`src="foo.css"`) are tracked. Capitalized React-style components (`<Script>`, `<Link>`) and expression containers (`href={someVar}`) are intentionally skipped because they have component-specific semantics that fallow can't statically resolve.

      In tagged templates, only the bare identifier tag `html` is matched. Other tags like `css`, `sql`, and `gql` are left alone. Asset references split across an interpolation boundary (`` html`<script src="${base}/app.js">` ``) are skipped rather than producing garbled specifiers.
    </Note>
  </Tab>

  <Tab title="JSDoc">
    Plain JavaScript files can reference TypeScript types through JSDoc `import()` expressions. Fallow extracts these references and marks the referenced types as used, so untyped JS files don't produce false unused-export reports.

    ```js app.js theme={null}
    /**
     * @param cfg {import('./types.ts').Config}
     * @returns {import('./types.ts').Result}
     */
    function boot(cfg) {
      return { ok: true };
    }
    ```

    Fallow tracks the `Config` and `Result` types from `./types.ts` as used, even though no `import` statement binds them. This works across all JSDoc tag contexts (`@param`, `@returns`, `@type`, `@typedef`, `@callback`) and supports union annotations with multiple `import()` expressions (`{import('./a').A | import('./b').B}`), nested member access, bare package specifiers, and parent-relative paths.

    <Note>
      Only `/** */` JSDoc blocks are scanned. Single-star `/* */` comments are not JSDoc and are ignored, matching the TypeScript compiler's behavior.
    </Note>
  </Tab>

  <Tab title="Astro">
    Astro components use a frontmatter block delimited by `---` at the top of the file. Fallow extracts everything between the two `---` delimiters and analyzes it as TypeScript.

    Fallow also follows per-component client scripts in the template body: `<script src="...">` references and ESM `import` statements inside inline `<script>` blocks. Astro bundles both into the page output at build time, so their targets stay reachable.

    ```astro Layout.astro theme={null}
    ---
    import Header from '../components/Header.astro'
    import Footer from '../components/Footer.astro'
    import type { Props } from './types'
    ---

    <html>
      <body>
        <Header />
        <slot />
        <Footer />
        <script src="../scripts/analytics.ts"></script>
        <script>
          import '../scripts/hydrate'
        </script>
      </body>
    </html>
    ```

    Fallow sees this file as importing `Header`, `Footer`, the `Props` type, plus `../scripts/analytics.ts` (external) and `../scripts/hydrate` (inline ESM).
  </Tab>

  <Tab title="MDX">
    MDX files can contain JavaScript `import` and `export` statements alongside Markdown content. Fallow extracts these statements and includes them in the module graph.

    ```mdx guide.mdx theme={null}
    import { CodeBlock } from '../components/CodeBlock'
    import { Callout } from '../components/Callout'

    export const meta = { title: 'Getting Started' }

    # Getting Started

    <CodeBlock language="bash">
      npm install fallow
    </CodeBlock>
    ```

    Fallow tracks the imports of `CodeBlock` and `Callout`, and the named export `meta`.
  </Tab>

  <Tab title="GraphQL">
    GraphQL document files can reference fragments from nearby `.graphql` and `.gql` files with `#import` comments. Fallow extracts those relative document links and keeps imported fragment files reachable.

    **What's supported:**

    * `#import "./fragment.graphql"` relative imports
    * `# import '../shared/fields.gql'` with optional whitespace after `#`
    * Extensionless relative imports such as `#import "./fragment"`, resolved through `.graphql` and `.gql`

    ```graphql query.graphql theme={null}
    #import "./fragments/user-fields"

    query CurrentUser {
      currentUser {
        ...UserFields
      }
    }
    ```

    ```graphql fragments/user-fields.graphql theme={null}
    fragment UserFields on User {
      id
      name
    }
    ```

    Fallow sees `query.graphql` as referencing `./fragments/user-fields`, probes `.graphql` and `.gql` when no extension is present, and marks `fragments/user-fields.graphql` as reachable.

    <Note>
      Only relative `#import` specifiers starting with `./` or `../` are tracked. Package specifiers and schema-loader syntax are intentionally ignored because they do not map to a local source document in the module graph.
    </Note>
  </Tab>

  <Tab title="CSS / SCSS Modules">
    Fallow tracks CSS and SCSS module files (`.module.css` and `.module.scss`) by extracting class names as named exports. When a component imports `styles` from a CSS module, fallow knows which classes exist.

    ```css Button.module.css theme={null}
    .root {
      display: flex;
    }

    .primary {
      background: blue;
    }

    .disabled {
      opacity: 0.5;
    }
    ```

    This file exports `root`, `primary`, and `disabled` as named exports.

    **CSS features fallow tracks:**

    | Feature                | Description                                                                       |
    | :--------------------- | :-------------------------------------------------------------------------------- |
    | `@import`              | CSS import statements create edges in the module graph                            |
    | `@use`                 | Sass `@use` rules are resolved as module imports                                  |
    | `@forward`             | Sass `@forward` rules are treated as re-exports                                   |
    | `@apply` / `@tailwind` | Detected as Tailwind CSS dependency usage                                         |
    | `@plugin`              | Tailwind v4 plugin sources are extracted as default imports (package or relative) |

    <Tip>
      When Tailwind is in your `package.json`, fallow recognizes `@apply` and `@tailwind` directives as evidence that the `tailwindcss` dependency is used, preventing false "unused dependency" reports. Tailwind v4 `@plugin "pkg"` directives credit their package or local plugin file directly.
    </Tip>
  </Tab>

  <Tab title="React Native">
    React Native projects use platform-specific file extensions for different implementations per platform. Fallow understands these extensions and treats them as variants of the same module.

    **Supported platform extensions:**

    | Extension                      | Platform               |
    | :----------------------------- | :--------------------- |
    | `.web.ts` / `.web.tsx`         | Web (react-native-web) |
    | `.ios.ts` / `.ios.tsx`         | iOS                    |
    | `.android.ts` / `.android.tsx` | Android                |
    | `.native.ts` / `.native.tsx`   | Native (iOS + Android) |

    ```text theme={null}
    src/
      Button.tsx          # Default implementation
      Button.web.tsx      # Web override
      Button.native.tsx   # Native override
    ```

    When another file imports `./Button`, fallow resolves it to all platform variants and considers each one reachable.
  </Tab>
</Tabs>

## See also

<CardGroup cols={2}>
  <Card title="Dead code analysis" icon="skull-crossbones" href="/analysis/dead-code">
    How fallow builds the module graph and detects unused code.
  </Card>

  <Card title="Built-in plugins" icon="puzzle-piece" href="/frameworks/built-in">
    95 framework plugins for automatic entry point detection.
  </Card>
</CardGroup>
