fast-diff
A fast, dependency-free JavaScript library for computing diffs between two strings using Myers' O(ND) algorithm.
Repository Health
Technical Analysis
fast-diff is a stripped-down import of Neil Fraser’s diff-match-patch library into the Node.js/browser environment, keeping only the diffing logic and removing the match and patch functionality along with several advanced options. What remains is a small, fast function for computing the difference between two strings as a sequence of insert, delete, and equal operations.
The core algorithm implements Myers’ “An O(ND) Difference Algorithm and its Variations” (1986) with a recursive divide-and-conquer strategy: common prefixes and suffixes are trimmed up front as a speedup, half-matches are located to split large problems into smaller independent diffs, and a bisecting middle-snake search handles the remaining cases. An optional cursor-position hint lets callers bias the result toward edits that make sense at a specific caret location, which is what makes the library popular as the diffing engine inside collaborative rich-text editors.
What You Get
- A single
diff(text1, text2, cursorPos, cleanup)function with no runtime dependencies - Tuple-based diff output (
[-1, "text"],[0, "text"],[1, "text"]) that’s trivial to render or replay - Cursor-aware diffing that favors edits matching a known caret position, added in v1.1
- Optional semantic cleanup pass to merge and simplify adjacent diff operations
- Shipped TypeScript type declarations (
diff.d.ts) alongside the CommonJS module - Convenience constants
diff.INSERT,diff.EQUAL,diff.DELETEfor readable comparisons
Common Use Cases
- Computing the minimal edit sequence between two versions of user-entered text
- Powering operational-transform/CRDT-style diffing inside rich-text editors (its best-known consumer is Quill)
- Generating inline insert/delete highlighting for text-comparison UIs
- Reconciling incremental updates to a string-based document model without diffing the whole document from scratch
Under The Hood
Architecture The library is a single procedural module (diff.js) ported almost verbatim from Google’s diff-match-patch, with match and patch functionality stripped out so only the diff pipeline remains. The public diff_main entry point short-circuits equal strings, applies a cursor-position override via find_cursor_edit_diff when a cursor hint is supplied, trims common prefixes/suffixes as a speedup, and hands the remaining middle block to diff_compute_. That function tries cheap wins first (pure insert, pure delete, substring containment) before checking diff_halfMatch_ to split the problem into two independent recursive diff_main calls, falling back to diff_bisect_ — a direct implementation of Myers’ middle-snake bisection — for the general case. Results are merged and optionally simplified through diff_cleanupMerge and diff_cleanupSemantic. There are no classes or DI: it’s a flat set of cooperating functions exported as one CommonJS entry point, so the only thing that would break from a core-abstraction change is the tuple shape itself.
Tech Stack
Plain JavaScript (CommonJS, module.exports), zero runtime dependencies, distributed as a single diff.js file plus a hand-authored diff.d.ts for TypeScript consumers (declared via the types field in package.json). Dev-only dependencies are lodash and seedrandom (used to build reproducible fuzz-test input) and nyc for coverage during npm test. There is no bundler or build step — the package is consumed directly as-is by Node or bundler toolchains, and CI (GitHub Actions, .github/workflows/test.yml) simply runs npm install && npm test on push/PR to master.
Code Quality There is no conventional assertion-based test framework (no Mocha/Jest/Vitest); instead test.js runs a fixed set of regression cases plus 10,000 seeded fuzz iterations (with and without cursor hints), verifying correctness by reconstructing text1/text2 from the emitted diff tuples and asserting they match exactly — a correctness-by-reconstruction strategy well suited to a pure algorithmic library. Coverage is measured via nyc. Naming and structure closely mirror the original diff-match-patch source (trailing-underscore “private” functions, non-camelCase names like diff_bisect_), which favors fidelity to the upstream algorithm over house style; there’s no linter or formatter configured in the repo. Error handling is minimal, which is reasonable for pure, side-effect-free string-processing code.
API Design
The public surface is deliberately tiny: one function, one options-order (text1, text2, cursorPos?, cleanup?), and three self-explanatory constants (diff.INSERT/DELETE/EQUAL) for reading tuple types back out. Getting started requires nothing more than require('fast-diff') and a single call — no configuration object, no class instantiation, no async ceremony. The README documents the exact return shape with a runnable example, and shipped TypeScript types give consumers autocomplete and tuple-literal typing ([-1 | 0 | 1, string]) without an extra @types package.
Used by 5 apps in this directory
Cherry Studio
AI Assistants
All-in-one AI desktop client with 300+ assistants and multi-model support
Enso
Analytics · Data Engineering · Low Code Platforms
A visual and textual programming platform for data prep and analysis where the node graph and the underlying Enso code are always perfectly in sync, built by an Alteryx co-founder on a GraalVM engine.
lila (Lichess)
Community
The forever-free, ad-free, open-source chess server powering millions of real-time games, AI analysis, puzzles, and tournaments worldwide.
Mathesar
Databases
Spreadsheet-like interface for your PostgreSQL database — self-hosted, no SQL required, native Postgres access control.
Standard Notes
Note Taking
End-to-end encrypted notes and files — private by design, built to last, and fully self-hostable.