Function signature
compareDocuments (
original : Buffer ,
revised : Buffer ,
options ?: CompareOptions
): Promise < CompareResult >
Compares two DOCX documents and returns a new DOCX with tracked-change markup that Word, Google Docs, and LibreOffice can display and accept/reject.
Example
import { readFile , writeFile } from 'node:fs/promises' ;
import { compareDocuments } from '@usejunior/docx-core' ;
const original = await readFile ( './contract-v1.docx' );
const revised = await readFile ( './contract-v2.docx' );
const result = await compareDocuments ( original , revised , {
author: 'Legal Review' ,
ignoreFormatting: true ,
reconstructionMode: 'rebuild' ,
});
await writeFile ( './contract-redline.docx' , result . document );
console . log ( 'Engine used:' , result . engine );
console . log ( 'Stats:' , result . stats );
// => Stats: { insertions: 12, deletions: 4, modifications: 0 }
Parameters
The original document as a Node.js Buffer. Read from disk with fs.readFile or receive from any source that returns binary data.
The revised document as a Node.js Buffer.
Optional comparison configuration. Show CompareOptions fields
Author name written into revision tracking (w:author). Default: "Comparison".
Revision timestamp used for generated track changes (w:date). Default: current time.
Ignore formatting differences when comparing. Default: true.
Atomizer-only normalization: merge adjacent <w:r> siblings with identical formatting before comparison. Reduces overly-granular diffs for heavily-fragmented documents. Default: true.
options.reconstructionMode
How to reconstruct the output DOCX when using the atomizer engine:
'rebuild' — rebuilds document.xml from scratch. More stable accept/reject behavior.
'inplace' — modifies the revised document AST in place. More experimental.
Default: 'rebuild'. See Comparison options reference for details. options.engine
'wmlcomparer' | 'atomizer' | 'auto'
Comparison engine to use:
'atomizer' — character-level comparison with move detection (recommended)
'auto' — automatically selects the best available engine (currently 'atomizer')
'wmlcomparer' — .NET WmlComparer; only available through the benchmark CLI, not programmatic access
Default: 'auto'.
Return value
Promise<CompareResult>
The resulting DOCX file with track-change markup. Write to disk or return as a response body.
Counts of changes detected in the comparison. Number of inserted text runs.
Number of deleted text runs.
Number of modifications (format or property changes).
engine
'wmlcomparer' | 'atomizer'
required
Which engine was used to produce the output.
reconstructionModeRequested
The reconstruction mode requested via options. Present for atomizer outputs.
The reconstruction mode that was actually used to produce the output. May differ from reconstructionModeRequested if the atomizer fell back. Present for atomizer outputs.
fallbackReason
'round_trip_safety_check_failed'
Why the requested reconstruction mode could not be used. Present only when the atomizer falls back from 'inplace' to 'rebuild'.
fallbackDiagnostics
ReconstructionFallbackDiagnostics
Detailed safety-check diagnostics for the fallback decision. Present only when the atomizer falls back. See Comparison options reference for the full type.
Removed engine
The 'diffmatch' engine has been removed from the public API. Passing engine: 'diffmatch' throws:
Error: The 'diffmatch' engine has been removed from the public API.
Use engine: 'atomizer' (recommended) or 'auto'.
Use 'atomizer' or 'auto' instead.
Detecting fallback
To detect when the atomizer falls back from 'inplace' to 'rebuild' mode (which may affect table structure fidelity), check result.reconstructionModeUsed:
const result = await compareDocuments ( original , revised , {
reconstructionMode: 'inplace' ,
});
if ( result . reconstructionModeUsed !== result . reconstructionModeRequested ) {
console . warn ( 'Fell back to rebuild mode:' , result . fallbackReason );
}
Or use the fail_on_rebuild_fallback option in the MCP save tool to surface this as an error automatically.