Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

seamwright

A dependency-free TypeScript CLI that diffs two text files using a from-scratch implementation of Myers' O(ND) shortest-edit-script algorithm, and renders the result as a colorized unified diff, a side-by-side view, or a stats summary.

Why it's interesting

Most people reach for diff -u and never think about how it decides which lines changed when many different edit sequences could turn file A into file B. seamwright implements Eugene Myers' 1986 algorithm itself — no diff binary, no npm diff library — including the classic O(ND) frontier search, backtracking through the trace to recover the actual edit script, and grouping the result into @@ ... @@ hunks with configurable context, the same way real unified diffs do.

Install / run

Requires Node.js 18+.

npm install
npm run build
node dist/src/cli.js <fileA> <fileB> [options]

Or try the bundled demo (builds, then diffs examples/before.txt against examples/after.txt):

npm run demo

Options

--mode <unified|side-by-side|stats>   output mode (default: unified)
--context <n>                         context lines for unified mode (default: 3)
--width <n>                           column width for side-by-side mode (default: 40)
--no-color                            disable ANSI colors
-h, --help                            show help

Exit code is 0 if the files are identical, 1 otherwise (handy for scripting).

Usage example

$ node dist/src/cli.js examples/before.txt examples/after.txt --no-color
@@ -1,10 +1,15 @@
  function greet(name) {
-   console.log("Hello, " + name);
+   console.log(`Hello, ${name}!`);
  }
  
+ function shout(name) {
+   console.log(name.toUpperCase());
+ }
+ 
  function farewell(name) {
    console.log("Goodbye, " + name);
  }
  
  greet("world");
+ shout("world");
  farewell("world");

Same diff, side by side:

$ node dist/src/cli.js examples/before.txt examples/after.txt --mode side-by-side --no-color
function greet(name) {           │ function greet(name) {
  console.log("Hello, " + name); │
                                 │   console.log(`Hello, ${name}!`);
}                                │ }

Or just the numbers:

$ node dist/src/cli.js examples/before.txt examples/after.txt --mode stats --no-color
similarity:    72.0%
unchanged:     9
insertions:    +6
deletions:     -1
edit distance: 7

How it works

  • src/myers.ts — the diff engine. It walks the "edit graph" (a grid where moving right deletes from A, moving down inserts from B, and moving diagonally means the lines matched) outward by increasing edit distance d, tracking only the furthest-reaching x-coordinate reached on each diagonal k = x - y for each d. That frontier search is what makes the algorithm O(ND) instead of the naive O(N·M) dynamic-programming table. Once the search reaches the bottom-right corner, it backtracks through the recorded frontiers (the "trace") to recover the actual sequence of equal/insert/delete operations — the shortest edit script.
  • src/render.ts — turns the flat op list into a diff -u-style unified view (grouping changes into @@ @@ hunks and collapsing long unchanged runs beyond the context window), a two-column side-by-side view, or a stats summary (similarity %, insertions, deletions, edit distance).
  • src/cli.ts — argument parsing and file I/O.

Tests

test/test.ts exercises the diff engine directly: it checks that replaying the returned op list reconstructs both the original and target sequences exactly, across identical inputs, empty inputs, pure insertions/deletions, full replacements, and a mixed case — plus a known-optimal edit-distance check for a single substitution.

npm test

License

MIT © neverlone

About

A from-scratch Myers diff CLI (TypeScript) rendering unified, side-by-side, and stats views.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages