Skip to main content
The @fallow-cli/fallow-node package exposes the main fallow analyses as async Node.js functions. No subprocess, no JSON parsing, no binary lookup: the bindings reuse the CLI orchestration layer and return the same JSON report envelopes the CLI emits for --format json. Use them when you want to embed fallow inside another tool, a Node.js server, an editor extension, or a custom script that otherwise would shell out to the CLI.

Install

npm install @fallow-cli/fallow-node
The package is a native NAPI-RS addon with platform-specific optionalDependencies for macOS (arm64, x64), Linux (gnu + musl on arm64 and x64), and Windows (x64). npm picks the matching binary at install time. Node 18 or newer is required.

Basic usage

import {
  detectDeadCode,
  detectDuplication,
  computeHealth,
} from '@fallow-cli/fallow-node';

const deadCode = await detectDeadCode({
  root: process.cwd(),
  explain: true,
});

console.log(deadCode.summary.total_issues);
console.log(deadCode.unused_exports);
Every function returns a promise resolving to the same JSON envelope the CLI emits when called with --format json: schema_version, summary, relative paths, injected actions arrays, and (when explain: true) a _meta block with docs links.

API

All six functions are async and accept an optional options object. Unknown fields are ignored. Enum-like fields take lowercase CLI-style literals ("mild", "cyclomatic", "handle", "low").
FunctionCLI equivalentReturns
detectDeadCode(options?)fallow dead-code --format jsonDeadCodeReport
detectCircularDependencies(options?)fallow dead-code --circular-depsDeadCodeReport filtered to the circular_dependencies category
detectBoundaryViolations(options?)fallow dead-code --boundary-violationsDeadCodeReport filtered to the boundary_violations category
detectDuplication(options?)fallow dupes --format jsonDuplicationReport
computeComplexity(options?)fallow health --format jsonHealthReport
computeHealth(options?)fallow health --format jsonAlias for computeComplexity with a product-oriented name

Shared options

Every options object extends AnalysisOptions:
FieldTypeDefaultPurpose
rootstringprocess.cwd()Project root directory
configPathstringauto-discoverPath to .fallowrc.json / fallow.toml
noCachebooleanfalseSkip the extraction cache
threadsnumberCPU countParallelism; must be > 0
productionbooleanfalseProduction mode (excludes test/build files)
changedSincestringunsetScope analysis to files changed since a git ref
workspacestring[]unsetRestrict to named workspace packages (monorepo)
changedWorkspacesstringunsetRestrict to workspaces whose files changed since a git ref. Mutually exclusive with workspace.
explainbooleanfalseInject a _meta block with metric / rule documentation

Dead-code options

detectDeadCode, detectCircularDependencies, and detectBoundaryViolations accept the same superset, DeadCodeOptions. Setting any of the filter booleans below restricts the report to the selected issue types; leaving them all unset returns every category (the CLI’s default behavior).
FieldType
unusedFiles / unusedExports / unusedDeps / unusedTypesboolean
unusedEnumMembers / unusedClassMembersboolean
unresolvedImports / unlistedDepsboolean
duplicateExports / circularDeps / boundaryViolations / staleSuppressionsboolean
filesstring[]Restrict to specific files (like fallow dead-code path/to/file.ts)
includeEntryExportsbooleanReport unused exports on entry files

Duplication options

DuplicationOptions adds duplication-specific fields on top of AnalysisOptions:
FieldTypeDefault
mode"strict" | "mild" | "weak" | "semantic""mild"
minTokensnumber50
minLinesnumber5
thresholdnumber0 (no limit)
skipLocalbooleanfalse
crossLanguagebooleanfalse
ignoreImportsbooleanfalse
topnumberunset

Complexity / health options

ComplexityOptions mirrors the fallow health flag surface:
FieldTypeNotes
maxCyclomatic, maxCognitivenumber (0 to 65535)Per-function thresholds
maxCrapnumberCRAP score ceiling
topnumberTruncate rankings
sort"cyclomatic" | "cognitive" | "lines"Finding sort order
complexity, fileScores, coverageGaps, hotspots, targets, scorebooleanEnable individual report sections
ownership, ownershipEmailsboolean + "raw" | "handle" | "hash"Ownership-aware hotspots
effort"low" | "medium" | "high"Filter refactoring targets
since, minCommitsstring, numberGit history window for hotspots
coverage, coverageRootstringIstanbul coverage file + root

Structured errors

Rejected promises throw a FallowNodeError (a plain Error with extra fields) that mirrors the CLI’s structured error surface:
import type { FallowNodeError } from '@fallow-cli/fallow-node';

try {
  await detectDeadCode({ root: '/does/not/exist' });
} catch (err) {
  const e = err as FallowNodeError;
  console.error(e.name);      // "FallowNodeError"
  console.error(e.message);   // "analysis root does not exist: ..."
  console.error(e.exitCode);  // 2
  console.error(e.code);      // "FALLOW_INVALID_ROOT"
  console.error(e.context);   // "analysis.root"
  console.error(e.help);      // optional remediation hint
}
The exit-code ladder matches the CLI: 0 ok, 2 generic / validation, 7 network (paid features only), etc.

When to use bindings vs the CLI

Use the bindingsUse the CLI
Embedding fallow in a long-running Node process (editor, devserver, CI runner)One-off invocation from a shell script or GitHub Action
You already have a Node runtime and want to skip subprocess + JSON parse overheadYou want zero runtime dependencies (native binary via npx fallow)
You need to call many analyses in sequence without re-initializingYou want CLI human output, progress bars, or interactive flags
You need typed access to the result envelope in TypeScriptYou consume the analysis from Rust, Python, Go, or any non-Node language
Both paths run the same analysis engine and return the same data. The bindings are not a reduced subset.

Limitations

  • The bindings wrap the one-shot analyses. Commands that write to the filesystem (fix, init, setup-hooks, audit --save-baseline, license activate, coverage setup) are not exposed.
  • No baseline or regression support yet. Use the CLI’s --baseline / --save-baseline flags for those workflows.
  • No watch mode. If you want incremental analysis, re-invoke the relevant function; fallow’s per-file cache makes repeat runs fast.
  • The API surface is young; breaking changes between minor versions are possible until it stabilizes.