Skip to main content
The CLI needs Node 22.17 or newer, or Bun. It depends on the parser and every plugin, so nothing else needs installing.

Narrating files

Each argument can be a file, a directory or a glob. Directories are searched recursively for .ts, .tsx, .js, .jsx, .mjs and .cjs files, skipping .d.ts files. With one file, the CLI prints its English. With several, it prints each file’s path followed by its English, indented. Problems such as syntax errors are printed to standard error, and the English is still printed.

Generated and vendored files

Inside directories and globs, and in diffs, the CLI skips code nobody wrote by hand:
  • dependencies, under node_modules, which are never searched
  • build output, under dist, .next, .nuxt, .output, .svelte-kit, .vercel, .turbo, .cache and coverage, and JavaScript under build or out
  • vendored code, under vendor and .yarn
  • lockfiles, .pnp.cjs, and *.min.js, *.bundle.js and *.chunk.js files
  • files that .gitattributes marks linguist-generated or linguist-vendored
  • files that start with a generated-code banner such as // Code generated by X. DO NOT EDIT. or @generated
  • minified files, recognised by very long lines
When narrating files, folders like dist are passed over silently, and the CLI prints to standard error how many other files it skipped because of their attributes or content. In a diff, each skipped file gets one line, such as .yarn/releases/yarn.cjs [deleted, skipped: vendored]. A file you name directly is always narrated, and --include-generated turns the skipping off.

Narrating diffs

narrator diff <base>..<head> compares two revisions, narrator diff <base>...<head> compares head with its merge base, and narrator diff <base> compares a revision with the working tree. Renamed files are detected with git’s rename detection, and moved or renamed declarations are matched across files. See Units and diffs. A file that can’t be read is listed with a line starting with ! that says why, for example ! Syntax error on line 12: Unexpected token, and the rest of the diff is narrated as usual. --json output includes the same information as skipped and problems on each file.

Options

Plugin names

From code

The package also exports main(argv, { extraPlugins }), which runs the CLI and returns an exit code, run({ argv, isTTY, extraPlugins, warn }), which returns the output as a string, and detectPlugins(dependencyNames), loadPlugins(names) and PLUGINS for building the same plugin selection yourself. extraPlugins adds your own codebase plugins after the detected ones, which is how to give the CLI your team’s vocabulary:
narrate.mjs