Skip to main content
A text diff tells you which characters changed. A Narrator diff tells you which sentences changed. To make that work, Narrator needs to know which part of the old file corresponds to which part of the new file. It does that with units.

Units

A unit is a top-level declaration together with the English lines that describe it. Each unit has a key, which is the declaration’s name, so the old and new versions of countOpenSeats can be matched even if the function moved within the file. Classes are split one level further, into a unit per member, so a change to one method does not pull the whole class into the diff.
units.ts
Output
Statements that are not declarations, such as a top-level app.get(...) call, get a key built from the callee and its first argument. When the same key appears twice in a file, the second one becomes key#2.

Diffing

narrator.diff(files) takes a list of changed files, each with its old and new source, and returns one report per file. For each pair of matching units it runs a line diff over the English, then pairs similar removed and added lines into modifications with word-level changes. The diff also looks across the whole change set:
  • A unit removed from one file and added to another with similar English is reported as moved, and the old location is marked moved-away.
  • A unit whose name changed but whose body reads almost the same is reported as renamed.
  • Long runs of unchanged lines are folded, keeping three lines of context around each change.
The Getting started page shows a complete diff example with real output.

Structured diffs

narrator.diffFiles(files) runs the same diff and returns FileDiff[], which keeps the Line objects instead of rendering HTML. Use it for terminals, JSON output, or your own renderer. renderDiffText({ files, format? }) prints it as indented text with - and + per sentence, and takes toAnsi as the format for colour. The CLI’s narrator diff uses both.
Each UnitDiff has the unit’s key, title, status, adds and dels, its rows, and for moves and renames an other that names the path and title it came from or went to. A row’s left and right cells each hold a line, and for modified rows, tokens that mark which words changed.

The HTML report format

narrator.diff returns FileJson[], a format built for rendering in a browser. Every cell carries HTML from toHtml and the source line range it describes, so a viewer can link each sentence back to the code.
Row kinds are same, add, del, mod (a modified line, with merged holding an inline word diff) and fold (hidden unchanged lines). Unit statuses are added, removed, modified, unchanged, moved, renamed and moved-away. For full control, call the lower-level functions yourself: fileNarrator(path).units(src, path) for each side, then diffUnits(before, after) and diffLines(a, b) from @usenarrator/core.