Built-in plugins
Get accurate results with zero configuration. Built-in plugins detect Next.js, Vite, Jest, Tailwind, ESLint, and many other tools, and tell fallow which files and exports each tool uses.
Built-in plugins give you accurate results without configuration. Without a plugin, fallow can report a route file, a config file, or a tool dependency as unused, because no import reaches it.
Fallow has built-in plugins for popular TypeScript and JavaScript tools. Each plugin tells fallow the conventions of one framework or tool: entry points, config files, used exports, and tooling dependencies.
Most plugins activate automatically when the relevant package is in your package.json. Some plugins (ESLint, Vitest) also activate when a config file is present in the workspace root, even without the package. This covers a monorepo that installs the tool at the root and gives the workspace packages their own config files.
| Plugin | Enabler packages |
|---|---|
| Next.js | next |
| Nuxt | nuxt, @nuxt/kit |
| Pinia | @pinia/nuxt |
| Remix | @remix-run/node, @remix-run/react, @remix-run/cloudflare, @remix-run/cloudflare-pages, @remix-run/deno |
| SvelteKit | @sveltejs/kit |
| Gatsby | gatsby |
| Astro | astro |
| Angular | @angular/core, ng-packagr |
| Ionic | @ionic/angular |
| React Router | @react-router/dev |
| RedwoodSDK | rwsdk (keeps src/worker.{ts,tsx,js,jsx,mts,mjs} reachable in rwsdk/vite apps) |
| TanStack Router | @tanstack/react-router, @tanstack/solid-router, @tanstack/start, @tanstack/react-start, @tanstack/solid-start, @tanstack/virtual-file-routes |
| React Native | react-native |
| Expo | expo |
| Firebase | firebase |
| NestJS | @nestjs/core |
| AdonisJS | @adonisjs/core |
| Docusaurus | @docusaurus/core |
| Nitro | nitropack |
| Capacitor | @capacitor/core, @capacitor/cli |
| Sanity | sanity, @sanity/ |
| VitePress | vitepress |
| next-intl | next-intl |
| Relay | relay-runtime, react-relay, relay-compiler |
| Electron | electron, electron-builder, @electron-forge/cli, electron-vite |
| Qwik | @builder.io/qwik, @builder.io/qwik-city, @qwik.dev/core, @qwik.dev/router |
| i18next | i18next, react-i18next, vue-i18n, next-i18next |
| Wuchale | wuchale, @wuchale/vite-plugin, or wuchale.config.js |
| Convex | convex; the safe in-project directory from convex.json#functions becomes the functions entry root when configured |
| Lit | lit, lit-element, @lit/reactive-element (native Custom Elements lifecycle methods are credited without a Lit dependency) |
| Lexical | lexical, @lexical/ (credits custom node lifecycle methods on DecoratorNode, ElementNode, TextNode subclasses) |
| Ember | ember-source, ember-cli, @embroider/core, @embroider/compat, @glimmer/component |
| Expo Router | expo-router |
| Supabase | supabase, or supabase/config.toml / supabase/functions/ present (treats supabase/functions/*/index.* as runtime entry roots) |
| Content Collections | @content-collections/core, @content-collections/vite, @content-collections/next, @content-collections/solid-start, @content-collections/remix-vite, @content-collections/qwik, @content-collections/vinxi |
| Contentlayer | contentlayer, contentlayer2, next-contentlayer, next-contentlayer2, or contentlayer.config.{ts,js,mts,mjs} present |
| Fumadocs | fumadocs-mdx, fumadocs-core, fumadocs-ui, or source.config.* present |
| Mintlify | mint, mintlify, or docs.json / mint.json present |
| Velite | velite, or velite.config.{ts,mts,cts,js,mjs,cjs} present |
| rspress | rspress, @rspress/ (credits the @theme / @theme-original virtual modules) |
| Obsidian | obsidian |
| Browser extension | webextension-polyfill, @types/chrome, @types/firefox-webext-browser |
| WXT | wxt, @wxt-dev/ |
| VS Code extension | vscode, @types/vscode, @vscode/test-electron |
| Plugin | Enabler packages |
|---|---|
| Vite | vite, rolldown-vite |
| Webpack | webpack |
| Rspack | @rspack/core, @rspack/cli |
| Rsbuild | @rsbuild/core |
| Rollup | rollup |
| Rolldown | rolldown |
| Tsup | tsup |
| Tsdown | tsdown |
| pkg-utils | @sanity/pkg-utils |
| Parcel | parcel, @parcel/ |
| Module Federation | @module-federation/enhanced, @module-federation/modern-js, @module-federation/nextjs-mf, @module-federation/node, @module-federation/rsbuild-plugin, @module-federation/rspack, @module-federation/runtime, @module-federation/vite, @module-federation/webpack-bundler-runtime, @originjs/vite-plugin-federation |
| Plugin | Enabler packages |
|---|---|
| Vitest | vitest or config file present |
| Jest | jest |
| Playwright | @playwright/test |
| Cypress | cypress |
| Mocha | mocha |
| Ava | ava |
| tap | tap |
| tsd | tsd |
| Storybook | storybook, @storybook/ |
| Karma | karma |
| Cucumber | @cucumber/cucumber |
| WebdriverIO | webdriverio, @wdio/ |
| k6 | k6, or *.k6.{js,ts,mjs,cjs,mts,cts} files present |
| Stryker | @stryker-mutator/core, stryker, or config file present |
| Plugin | Enabler packages |
|---|---|
| ESLint | eslint, @eslint/js, or config file present |
| Biome | @biomejs/biome |
| Stylelint | stylelint |
| Prettier | prettier |
| Oxfmt | oxfmt |
| Oxlint | oxlint |
| markdownlint | markdownlint, markdownlint-cli, markdownlint-cli2 |
| CSpell | cspell |
| Remark | remark, remark-cli |
| Plugin | Enabler packages |
|---|---|
| TypeScript | typescript |
| Babel | @babel/core |
| SWC | @swc/core, @swc/cli |
| Plugin | Enabler packages |
|---|---|
| Tailwind | tailwindcss, @tailwindcss/postcss |
| PostCSS | postcss |
| UnoCSS | unocss, @unocss/* |
| PandaCSS | @pandacss/dev |
| Plugin | Enabler packages |
|---|---|
| Prisma | prisma, @prisma/client |
| Drizzle | drizzle-orm |
| Knex | knex |
| TypeORM | typeorm |
| Kysely | kysely, kysely-ctl |
| Plugin | Enabler packages |
|---|---|
| Turborepo | turbo |
| Nx | nx |
| Changesets | @changesets/cli |
| Syncpack | syncpack |
| pnpm | pnpm-workspace.yaml or pnpm-lock.yaml present |
| Plugin | Enabler packages |
|---|---|
| semantic-release | semantic-release |
| Commitlint | @commitlint/cli |
| Commitizen | commitizen |
| commit-and-tag-version | commit-and-tag-version, standard-version |
| Vercel | vercel, @vercel/config |
| Wrangler | wrangler |
| OpenNext Cloudflare | @opennextjs/cloudflare, or an opennextjs-cloudflare command in a package.json script |
| Sentry | @sentry/nextjs, @sentry/react, @sentry/node, @sentry/browser |
| Danger | danger |
| Plugin | Enabler packages |
|---|---|
| husky | husky |
| lint-staged | lint-staged |
| lefthook | lefthook, @evilmartians/lefthook |
| simple-git-hooks | simple-git-hooks |
| Plugin | Enabler packages |
|---|---|
| GraphQL Codegen | @graphql-codegen/cli |
| TypeDoc | typedoc |
| openapi-ts | openapi-typescript |
| Plop | plop |
| SVGO | svgo |
| SVGR | @svgr/core, @svgr/cli, @svgr/webpack, @svgr/rollup, @svgr/vite |
| size-limit | size-limit (credits @size-limit/* and size-limit-* presets and plugins) |
| c8 | c8 |
| nyc | nyc |
| MSW | msw |
| nodemon | nodemon |
| PM2 | pm2 |
| dependency-cruiser | dependency-cruiser |
| Hardhat | hardhat |
| Bun | bun-types, @types/bun |
| Deno | deno.json or deno.jsonc present |
| napi-rs | A napi field with targets in package.json, plus optionalDependencies |
| Varlock | varlock, @varlock/, or .env.schema present |
| OpenCode | opencode.json, .opencode/, or @opencode-ai/ (credits auto-loaded plugin files and opencode.json plugin dependencies) |
Plugins with deep config parsing
These plugins do more than detect a package. They parse your config files with the Oxc AST parser and extract entry points, dependencies, aliases, and other settings automatically:
| Plugin | What it extracts |
|---|---|
| ESLint | Plugin imports, shared configs, custom rule paths, import resolver packages |
| Vitest | Reporters, coverage provider, typecheck checker, browser provider from vitest.config.ts |
| Vite | Entry points, resolve.alias mappings, plugin imports from vite.config.ts |
| Jest | Setup files, transform paths, module mappers from jest.config.js |
| tsd | Declaration test directory from package.json#tsd.directory |
| Storybook | Story globs, addon imports from .storybook/main.ts. Fallow resolves each stories pattern against the .storybook/ directory, as Storybook does. See Storybook stories |
| Tailwind | Content paths, plugin imports from tailwind.config.js |
| Webpack | Entry points including descriptor/context forms, resolve.alias mappings, loader/plugin imports from webpack.config.js. An entry value that names a package instead of a file credits that dependency, with the resource query included (webpack-hot-middleware/client?reload=true credits webpack-hot-middleware). A glob-shaped value stays an entry pattern. Fallow also reads a config under config/, build/ or webpack/ when it exports a webpack configuration; see config directories. Inline loader requests (!raw-loader!./file.js) resolve to their resource; see inline loader requests |
| TypeScript | Path aliases, project references from tsconfig.json |
| Babel | Plugin and preset imports from babel.config.js |
| Rollup | Entry points, plugin imports from rollup.config.js |
| Rolldown | Entry points, external deps, plugin imports from rolldown.config.ts |
| PostCSS | Plugin imports from postcss.config.js |
| Nuxt | Modules, plugins, server routes, alias, imports.dirs, components, srcDir from nuxt.config.ts. Fallow reads the config of each root separately: the project root and every workspace root. The custom components: or imports: shape of one app decides the autoImports verdict for that root only. See local layers |
| SvelteKit | kit.alias mappings, param matchers from svelte.config.js |
| Next.js | App Router convention exports (page, layout, loading, error, route), route segment config, Pages Router exports, middleware, proxy, instrumentation, mdx-components, transpilePackages |
| Rsbuild | Entry points, plugin imports from rsbuild.config.ts. A source.entry value that names a package credits that dependency, with the resource query included. A glob-shaped value stays an entry pattern. root applies to a relative entry, the same way context applies for Rspack |
| Rspack | Entry points, plugin imports from rspack.config.js. An entry value that names a package credits that dependency, with the resource query included. A glob-shaped value stays an entry pattern. context applies to a relative entry. An entry without an extension matches the source file or the directory index |
| Remark | Plugin imports from .remarkrc.js |
| Angular | Styles, scripts, main, polyfills from angular.json build targets. The ng-packagr lib.entryFile in ng-package.json or ng-package.prod.json (default src/public_api.ts, resolved relative to the config directory) becomes a library public API entry point. Fallow also scans nested secondary-entry-point configs in the package subtree. @Component({ templateUrl, styleUrl }) decorator references create graph edges. Standalone .html templates and inline template: literals both add synthetic <template> complexity findings (@if/@for/@switch/@defer, *ngIf, bound attributes, interpolations). To suppress them, use <!-- fallow-ignore-file complexity --> (external) or // fallow-ignore-next-line complexity above the @Component decorator (inline) |
| Nx | Executor references, main entry points, tsconfig paths from project.json |
| Hardhat | Plugin imports and side-effect requires from hardhat.config.ts |
| Contentlayer | contentDirPath, same-file defineDocumentType filePathPattern entries, and config imports from contentlayer.config.* |
| Velite | defineCollection pattern globs joined to the top-level root (default content), generated .velite output, a non-default output.data dir, and config imports from velite.config.* |
| UnoCSS | Preset and transformer imports from uno.config.ts |
| Wuchale | Adapter imports from wuchale.config.js; static custom JavaScript config files referenced from @wuchale/vite-plugin in vite.config.* |
| Module Federation | exposes targets, remotes aliases and shared packages from module-federation.config.* and from a Federation plugin call in a webpack, rspack, rsbuild, vite or next.config.* file. Remotes from literal runtime calls such as registerRemotes and loadRemote. See Module Federation |
Run fallow list --plugins to see which plugins are active in your project.
Active plugins:
- nextjs
- vite
- vitest
- playwright
- storybook
- oxlint
- typescript
- tailwind
- drizzle
If your framework is not in the list, write a custom plugin. Custom plugins support any internal or third-party tool, with declarative JSON or TOML.
Webpack config directories
Fallow also reads a webpack config that lives under config/, build/ or webpack/ instead of the package root. Rspack and rsbuild configs stay at the package root; they do not have this directory rule.
A file under config/ or webpack/ counts as a webpack config when it exports a webpack configuration: an object with a webpack config key other than name or dependencies (also returned from a function), an array of configurations, or a webpack-merge call (merge, mergeWithCustomize, mergeWithRules, or the imported package). A helper file such as config/webpack.paths.js does not export a configuration, so fallow still reports it as unused when nothing imports it.
build/ also holds build output, so fallow reads a narrower name there: only webpack.<target>.{ts,js,mjs,cjs}, such as build/webpack.prod.js, and only when it passes the same export check. Fallow never reads build/webpack.config.*, because that name is more likely to be a compiled or stale copy.
Fallow probes these directories beside a root config, so build/webpack.prod.js is read together with a root webpack.config.js.
Entries resolve like the bundler resolves them:
- Rspack reads
context, and rsbuild readsroot. A relative entry, and a Module Federationexposestarget, resolve against that directory. - An entry without an extension, such as
./libor./src/app, matches the source file (./lib.ts) or the directory index (./lib/index.ts). This also applies whencontextorrootis set. - A Module Federation
exposestarget and theremotesscope of a webpack config inconfig/,build/orwebpack/resolve against the package root, the same as webpack does withoutcontext.
Webpack inline loader requests
An import can name its loaders inline, such as require('!raw-loader?esModule=false!./shim.js'). Fallow reads these requests in every project, also when the webpack plugin is not active:
- The request resolves to its resource, the last segment (
./shim.js). The!,!!and-!prefixes and the?optionsof each loader do not change the target. - Each loader package, such as
raw-loader, counts as a used dependency. A loader indevDependenciesis not reported as a dev dependency that production code uses. - A loader replaces the exports of its resource. A loader import therefore uses every value export of the resource,
defaultincluded, and fallow does not report these exports as unused. A type export of the resource (a type alias or an interface) follows the same rule as a type export of a file that a dynamic import pattern matches: only an import that names it uses it. - A text loader returns the text, the bytes or a URL of the file:
raw-loader,file-loader,url-loader,text-loaderand similar. The resource counts as used, but its own imports do not. They do not keep other files in use, and they are not production imports. A loader that runs the file, such asworker-loader,css-loaderorbabel-loader, keeps the imports of the resource. - A text loader import does not run the resource, so it does not cross an architecture boundary, it does not carry server code into a
"use client"file forclient-server-leak, and a re-export through a loader is not a client or server origin of a mixed client/server barrel. A package file behind a text loader (raw-loader!pkg/notes.txt) is read at build time: the package is a used dependency, but not a dev dependency that production code imports. - A worker loader runs the resource in another thread:
worker-loader,sharedworker-loader,worklet-loader,workerize-loader,comlink-loader,service-worker-loaderand similar. The import loads the same way asnew Worker(new URL('./work.js', import.meta.url)). A cycle through the import is reported by default, andcircularDependencies.ignoreLazyImportsskips it.fallow list --entry-weightcounts the resource as out-of-thread code, not as startup code. - A
!is also valid in a file name. A request without a prefix, such as./we!rd.jsorpkg/a!b.js, resolves as a plain path first when that file exists, also an installed package file. When the file does not exist, for example in a clone without installed packages, fallow reads the request the way webpack does: webpack splits every request on!, sopkg/a!b.jsis the loaderpkg/aforb.js. - Only inline loaders change an import. A loader that a rule in
module.rulesof a webpack config applies, such as{ test: /\.worker\.js$/, use: 'worker-loader' }, gives no worker or text loader semantics. The rule conditions (test,include,exclude,issuer,resourceQuery, theoneOforder) use JavaScript regular expressions and computed paths, and many projects build the rules in code, for example withwebpack-merge, in thewebpackfunction ofnext.config.js, or in StorybookwebpackFinal. A static read would miss or misapply rules, and a misapplied text loader rule would hide the imports of every file that it matches. The configured loader packages still count as used dependencies. - When the resource does not resolve, the unresolved import shows the full request, so an
ignoreUnresolvedImportsentry must use the full request.
Module Federation
With Module Federation, fallow keeps exposed modules out of the unused-file report, does not report remote imports as unlisted dependencies, and does not report shared packages as unused dependencies.
Fallow reads exposes, remotes, and shared from module-federation.config.{ts,js,mjs,cjs,mts,cts}. It also reads them from a Federation plugin call in a webpack, rspack, rsbuild, vite or next.config.* file. Fallow recognizes these plugin calls: ModuleFederationPlugin, NextFederationPlugin, moduleFederationPlugin, pluginModuleFederation and federation. Fallow reads such a call wherever it is in the config program. A call counts only when its first argument is an object that declares exposes, remotes, or shared.
exposes: each target becomes a runtime entry point. The exposed module, and everything it reaches, stays out ofunused-file. Its exports followincludeEntryExports, like the exports of any other entry point. A target that names a bare module request instead of a local path ("./utils": "shared-utils") credits that dependency, but only in the package that owns the config.remotes: fallow treats each alias and its subpaths as provided by the remote container, so it does not reportimport("checkout/Button")as an unlisted dependency. The alias holds only under the directory of the config that declared it. A sibling workspace package that declares no remote still reports the dependency.shared: each package that the option names counts as used, so it does not report as an unused dependency. Fallow reads the object form (shared: { react: { singleton: true } }), the array form (shared: ['react', 'react-dom']), an object element in the array form, and theimportandpackageNamefields of an entry descriptor. A key with a trailing/credits the same package. A relative key shares a project module and credits no package. The credit applies only to the package that owns the config (the nearestpackage.jsonat or above the config), so a sibling workspace that declares the same package and does not use it still reports it. Asharedentry for a package thatpackage.jsondoes not declare creates no finding. Asharedvalue that fallow cannot read gives no credit and records no diagnostic.
Fallow reads a plugin call in these positions:
- A nested plugin array, and a plugin list that a variable holds.
- A tool-specific key such as
tools.rspack.plugins. - A hook body, such as an rsbuild
appendPluginshook or a Next.jswebpack(config)hook. - A helper module that the bundler config imports with a relative
importorrequire, such asconfig/module-federation.js. Fallow reads the helper one import deep, inside the project root, as if the call was in the config. The diagnostics and the trace sources name the helper file.
Fallow also reads the plugin options through one step of indirection:
- An
export constin the same file (export const mfConfig = { ... }), and a plainconst(const mfConfig = { ... }). The program must have one binding of that name, and no code may write to the binding or to one of its members. - A TypeScript non-null assertion on the binding, such as
new ModuleFederationPlugin(mfConfig!). - A computed callee, such as
new container['ModuleFederationPlugin']({ ... }). - A relative
importof a sibling config file, including a default import and a named import. - A relative
requireof a sibling config file, one step deep. Arequireof a package stays silent. - An object spread over a same-file binding (
{ ...base }) andObject.assign({}, base). - The array form of
exposes. A string element is both the public name and the module request. An object element uses the object reader. exposestargets and theremotesscope of a webpack config underconfig/,build/orwebpack/, resolved against the package root, as webpack does withoutcontext. See config directories.
Every config reader that resolves an options object, not only Module Federation, follows export const config = { ... }; export default config the same way.
Fallow does not read:
- The array form of
remotes. A bundler derives the request scope of an element from the whole container location, so the alias is not a bare specifier. - A value that is not a static object literal, an unreadable
requireof a package, and an array element that holds glob syntax, a nested array, or a value that is not a string. - A spread over a binding fallow cannot resolve. This records a
plugin-config-unreadablediagnostic with thespreadreason for each Federation key the readable part does not declare. When the options declare no Federation key at all, a barefederation(...)call records nothing, because other libraries use that name too.
Runtime remotes
A remote can also come from a call to the Federation runtime. Fallow reads these calls in a file that imports them from @module-federation/runtime or @module-federation/enhanced/runtime, by name, by a renamed import, or through a namespace import. A local function with the same name registers nothing.
registerRemotes([{ name: 'checkout', entry }])registerscheckout, and a literalaliaswhen the object has one.loadRemote('checkout/Button')registerscheckout. A scoped name keeps two segments (@scope/remote).init({ remotes })andcreateInstance({ remotes })register the remotes that theirremotesoption names. Fallow also reads theregisterRemotesandloadRemotemethods of the instance that they return.
A remote from a runtime call follows the same rule as a remotes entry: the alias and its subpaths are provided only inside the workspace that holds the file. Fallow also reads these calls in the <script> blocks of a .vue or .svelte file. The blocks count as one file, so an import in one block covers a call in another.
Fallow reads only a static literal argument. A call whose argument is not a static literal, such as loadRemote(`${scope}/${module}`), records a plugin-config-unreadable diagnostic on the source file, with the function name as key and the reason dynamic-argument.
Trace the Federation source
--trace-file and --trace-dependency name the Federation config when it is the reason for the result:
--trace-fileon a file that anexposesentry makes an entry point lists each config that exposes it.--trace-dependencyon aremotesalias lists each config that declares the alias, and says that a remote container provides the name, not an npm package.
The human output adds one Source: line for each config. The JSON output has a sources array with { kind, plugin, config, key } entries, for example { "kind": "module-federation", "plugin": "webpack", "config": "packages/cart/webpack.config.js", "key": "exposes" }. For a remote that only a runtime call names, config is the source file and key is the function name. A trace with no Federation involvement has no sources array. The MCP trace_file and trace_dependency tools have the same field.
Limits and diagnostics
Fallow reads the config syntactically. It fetches no remote container and validates nothing about the remote. Fallow does not check the availability of the remote, its exports, its versions, or its shared singletons.
When fallow cannot read a declaration in full, it adds a plugin-config-unreadable entry to workspace_diagnostics[] and prints a warning on stderr. The entry names the plugin, the key, and the reason, with the config file in path. For a runtime call, path is the source file.
reasonisnot-object-literal,array-form,spread,unreadable-entriesordynamic-argument. For a runtime call,keyisregisterRemotes,loadRemote,initorcreateInstance. More values can come later, so do not treat this list as closed.- The plugin is
module-federationfor a standalone config file and for a runtime call. It iswebpack,rspack,rsbuild,viteornextjswhen fallow read the options from the config of that plugin. - Two unreadable keys in one file give two entries.
- The entry has
degrades_analysis, so both CI integrations that fallow ships report it under degraded inputs.
fallow: Plugin 'module-federation': `exposes` in 'module-federation.config.ts' is not a static object literal, so the targets are not registered as entry points. Name the exposed files in `dynamicallyLoaded`.
fallow: Plugin 'webpack': `remotes` in 'webpack.config.js' uses the array form, which is not read yet, so the aliases are not treated as provided by a remote container. Name the aliases in `ignoreDependencies`, or declare them as the keys of an object literal, whose values may be computed.
For an exposed file that fallow cannot see, use dynamicallyLoaded. For a file that is a project entry point of its own, use entry. Put a remote alias in ignoreDependencies. Note that ignoreDependencies also hides unused-dependency findings for that name.
Nuxt local layers
Nuxt lets a project extend other Nuxt codebases, called layers. Fallow scans a local layer the same way it scans the project root.
A directory is a local layer when it holds a nuxt.config file (ts, js, mjs, cjs, mts or cts), and either:
- A
nuxt.confignames it inextends, as a relative path. This includes the project root config and the config of any local layer already found, so a layer chain (a layer that itself extends another local layer) resolves too. - It sits under
layers/<name>, beside the root config. Fallow scans everylayers/<name>directory that has anuxt.config, without anextendsentry.
A local layer without a nuxt.config is not a layer, so its files keep reporting as unused when nothing references them.
For each local layer:
- Its convention files (pages, layouts, components, composables, utils, server, plugins) are entry points, the same as the project root.
- Its root files (
app.vue,app.config.*) are always used. - With
autoImportson, its components and composables are auto-import sources. An unreferenced layer component then reports asunused-file. - Its own
nuxt.configtakes part in theautoImportssurface classification, alongside the root config. The advisory that fallow prints for a customcomponents:orimports:shape names the config file that decided that surface.
#layers/<name>/ resolves to a local layer by its $meta.name:
- A
layers/<name>directory without a$meta.nameresolves by its directory name. - An
extendslayer without a$meta.namegets no alias, so an import through#layers/<name>/stays unresolved.
A remote layer (a github: or gh: reference) or a package layer (an npm name) stays a dependency reference only. Fallow does not scan its files.
Fallow reads the modules of a package layer, so a module that the layer registers is active for the app. For example, with extends: ['docus'], or another package layer that lists @nuxt/content in its own modules, the components/content/ files and the content.config.* file of the app stay entry points. Fallow reads the nuxt.config of the layer from the nearest node_modules/<name>. docus activates @nuxt/content also when it is not installed. Fallow does not follow the extends of a package layer. A local layer that registers @nuxt/content also marks the content.config.* file of the app as used.
Nuxt auto-import scope
With autoImports on, an auto-import name marks as used only the files of the app that renders or calls it, and of the layers that this app extends. In a monorepo, a <Card /> in one app does not keep the unused Card.vue of another app. A run with autoImports on can therefore report more unused files than before.
- A layer that an app extends by a relative path outside the app, or by the package name of a workspace, shares its names with that app in both directions. The app uses the components and Pinia stores of the layer. A layer layout can render a component that the app overrides.
- Two apps that extend the same layer do not see the names of each other.
These component files stay entry points, because fallow cannot see how they render:
- Files in
components/global/and*.global.vuefiles. A string reference such asresolveComponent('Name')can render a global component. - Files in
components/content/of the project and of each local layer, when@nuxt/contentis inmodules. Markdown content renders these components, and fallow does not read Markdown.
nuxt-og-image renders the template that a string names, so no import or template tag reaches the file. A defineOgImage('Docs.takumi') or defineOgImageComponent('Docs') call marks the matching file as used, under an OgImage/, og-image/, OgImageCommunity/, or OgImageTemplate/ components directory. The name match is the one that nuxt-og-image uses: dot segments join in PascalCase, and the renderer suffix (.satori, .browser, .takumi) and the directory prefix do not count. A template that no call names with a static string still reports as unused.
Storybook stories
Storybook reads each stories pattern in .storybook/main relative to the directory of that config file. Fallow does the same, so a pattern such as ../src/**/*.mdx matches the story files that Storybook loads.
- A pattern can point into another workspace of the project. For example, a central docs app with
apps/docs/.storybookandstories: ["../../../packages/ui/src/**/*.docs.tsx"]marks the matching files inpackages/uias used. - Fallow drops a pattern that leaves the project root.
- Storybook reads a leading
/as an absolute filesystem path. A pattern such as/src/**outside the project therefore marks nothing as used. - A
@(ts|tsx)group, as in the Storybook config template, matches like{ts,tsx}. A nested@(..)group matches too. Other extglob forms, such as!(..), match nothing. - Fallow reads the object form
{ directory, files, titlePrefix }.directoryresolves against the.storybook/directory, andfilesapplies under it. Withoutfiles, the Storybook default**/*.@(mdx|stories.@(js|jsx|mjs|ts|tsx))applies. - Fallow also reads the
.storybook/mainconfig of a workspace when the root package uses Storybook too.