Known limitations
Know where fallow can miss a finding or report a false positive, and how to work around it. Covers the limits of syntactic analysis, runtime patterns, and framework edge cases.
This page lists the patterns where fallow can miss a finding or report a false positive, with a workaround for each.
The default fallow analysis is syntactic. It does not use the TypeScript
compiler or resolve types. The optional --type-aware
pass adds limited checker evidence for the project questions that fallow
answers. It does not make fallow a compiler or a general typed linter.
Each limitation below applies to a specific pattern. Most of them do not affect a standard TypeScript project with isolatedModules: true.
Syntactic analysis only (no TypeScript type information)
By default, fallow parses source code into syntax trees with Oxc, and uses
oxc_semantic for scope-aware binding analysis. It does not run the
TypeScript compiler or resolve type information, so the default path stays
fast. Add --type-aware for exact symbol identity,
private type leaks across files, targeted tests, and public type coupling.
Impact: Fallow handles type-only imports (import type { Foo }) correctly. It also tracks value imports that are used only as type annotations (e.g., import { Foo } followed by const x: Foo), with oxc_semantic reference counting. To detect conditional type exports or dead code behind generic interfaces, fallow needs real type resolution.
Workaround: Set isolatedModules: true in tsconfig.json. esbuild, swc, and Vite already require this setting, so most modern projects have it. With isolatedModules, every import is either an explicit import type or a real value import, so there is no ambiguity.
{
"compilerOptions": {
"isolatedModules": true
}
}Svelte export let prop ambiguity
In Svelte components, an export let declaration defines a component prop and a regular export. Fallow cannot tell props (which consumers use through the template) apart from utility exports that can really be unused.
Impact: Fallow can miss some unused exports in .svelte files.
Workaround: There is no configuration workaround. Review Svelte component exports manually. Move utility functions into separate .ts files, where fallow can track them accurately.
This limitation applies only to export let prop detection. Since v2.15.0, fallow does track imports that the template uses. It counts these as used:
- Component tags.
- Directives (
use:tooltip,v-focus-trap). - Expressions.
$storesubscriptions in Svelte.v-onandv-bindobject syntax in Vue.
File types has the details.
CSS and SCSS extraction
Fallow reads import directives and all SCSS syntax with regex extraction, not with a full parser. For CSS Module class names in standard CSS files, fallow uses a CSS parser (lightningcss). The parser does not read SCSS syntax, so .module.scss class names also come from regex extraction.
What's tracked:
@importand@usestatements@forwardrules@applyand@tailwinddirectives (as Tailwind dependency usage)@plugindirectives (Tailwind v4 plugin sources, package or relative)
What's not tracked:
composes:(CSS Modules composition). A class that another class composes can show as unused.- The scope of
:global(). Fallow reads the class inside:global(.name)as a CSS Module class, so it can report a global class as unused. - Complex selector-based dependencies
Workaround: If fallow reports false positives for CSS files that use composes: or :global(), suppress them with ignorePatterns or inline comments.
{
"ignorePatterns": ["**/legacy-styles/**/*.css"]
}NestJS and dependency injection class members
Fallow tracks class member usage syntactically: it looks for direct references in source code. In NestJS and other DI frameworks, the DI container can call abstract class methods at runtime, with no direct reference in the source.
Impact: Fallow can report abstract class methods and properties that dependency injection uses as unused.
Workaround: In a project that uses DI a lot, disable unused-class-members:
{
"rules": {
"unused-class-members": "off"
}
}Library consumer types (noisy but correct)
If your package exports types for external consumers (e.g., ButtonProps, Config), fallow reports them as unused in your project. The finding is correct, because no internal file imports them.
Impact: Library authors get correct findings that add noise.
Workaround: Mark the public API files with ignoreExports:
{
"ignoreExports": [
{ "file": "src/index.ts", "exports": ["*"] },
{ "file": "src/types.ts", "exports": ["*"] }
]
}Config parsing ceiling
The built-in fallow plugins parse config files (e.g., vite.config.ts, jest.config.js) with the Oxc AST parser. The parser handles static objects, arrays, and defineConfig() wrappers, but it cannot evaluate arbitrary JavaScript.
What's handled:
- Static object literals and arrays
defineConfig()/module.exportswrappers- String concatenation in simple cases
What's not handled:
- Computed property keys
- Conditional expressions (
process.env.NODE_ENV === 'production' ? ... : ...) - Nested factory functions
- Dynamic
require()with variables
Workaround: Add the entry points that fallow misses to your fallow config manually:
{
"entry": ["src/dynamic-entry.ts", "scripts/*.ts"]
}React Native native modules
Fallow does not detect auto-linked React Native native packages (installed via npx pod-install or auto-linking) as used. These packages can have no explicit import in JavaScript code.
Impact: Fallow can report auto-linked packages such as react-native-screens or react-native-gesture-handler as unused dependencies.
Workaround: Add auto-linked packages to ignoreDependencies:
{
"ignoreDependencies": [
"react-native-screens",
"react-native-gesture-handler",
"react-native-safe-area-context"
]
}