Browser-based PDF comparison tool with visual diff highlighting. Zero system dependencies, pure JavaScript, client-side processing.
npm install pdf-diff-viewerbash
npm install pdf-diff-viewer
`
$3
`javascript
// Import the library
import PDFDiffViewer from 'pdf-diff-viewer';
// Or in browser (after including the script)
//
// Create an instance
const viewer = new PDFDiffViewer('#results-container', {
scale: 3.0,
labelA: 'Original',
labelB: 'Modified',
highlightAlpha: 0.32
});
// Compare PDFs (accepts File objects, ArrayBuffers, or Uint8Arrays)
const fileA = document.getElementById('fileA').files[0];
const fileB = document.getElementById('fileB').files[0];
viewer.compare(fileA, fileB)
.then(results => {
console.log('Comparison complete:', results);
console.log('Total pages:', results.totalPages);
console.log('Total diff pixels:', results.totalDiffPixels);
})
.catch(error => {
console.error('Comparison failed:', error);
});
`
$3
`html
PDF Comparison
`
$3
Run as a standalone web server:
`bash
npx pdf-diff-viewer
`
Then open your browser to http://localhost:3000
Custom port:
`bash
PORT=8080 npx pdf-diff-viewer
`
$3
Simply open public/index.html directly in your browser - no server or npm required!
š How It Works
1. Select two PDF files using the file inputs (or pass them programmatically)
2. Click "Compare PDFs" (or call viewer.compare(pdfA, pdfB))
3. View the visual diff with highlighted differences
4. Red highlights show changed or different content
5. Auto-alignment compensates for minor layout shifts
š API Reference
$3
`javascript
new PDFDiffViewer(container, options)
`
Parameters:
- container (string|HTMLElement) - CSS selector or DOM element to render results
- options (Object) - Configuration options
Options:
- scale (number) - PDF rendering scale, default: 3.0 (~300 DPI)
- maxShift (number) - Max pixel shift for alignment, default: 3
- colorTolerance (number) - Color difference threshold, default: 120
- minHighlightArea (number) - Min area to highlight in pixels, default: 60
- minWordSize (number) - Min word box size in pixels, default: 8
- highlightAlpha (number) - Highlight transparency (0-1), default: 0.32
- highlightColorA (string) - Hex color for Document A highlights, default: '#FF1744' (red)
- highlightColorB (string) - Hex color for Document B highlights, default: '#2196F3' (blue)
- backgroundFillColor (string) - Canvas background fill color, default: 'white'
- labelA (string) - Label for first document, default: 'Document A'
- labelB (string) - Label for second document, default: 'Document B'
- showPageNumbers (boolean) - Show page numbers, default: true
- cropRegions (Array) - Regions to crop: [{ page: 1, x, y, width, height }]
- maskRegions (Array) - Regions to mask/ignore: [{ page: 1, x, y, width, height }]
- alignmentTolerance (number) - Search range for matching pages (+/- pages), default: 2
- similarityThreshold (number) - Minimum text similarity (0-1) for page matching, default: 0.3
$3
#### compare(pdfA, pdfB)
Compare two PDFs and render results.
Parameters:
- pdfA (File|ArrayBuffer|Uint8Array) - First PDF
- pdfB (File|ArrayBuffer|Uint8Array) - Second PDF
Returns: PromisetotalPages - Number of pages compared
- totalDiffPixels - Total different pixels across all pages
- pageResults - Array of per-page results
- pageMapping - Page alignment mappings (when smartAlignment is enabled)
#### getResults()
Get the most recent comparison results.
Returns: Object|null - Last comparison results
#### clear()
Clear the viewer and remove all rendered content.
#### destroy()
Destroy the viewer instance and clean up resources.
š§ Technical Details
$3
- Frontend: AngularJS with PDF.js for rendering
- PDF Rendering: PDF.js at 3x scale (~300 DPI)
- Comparison Engine: Custom pixel-diff algorithm with alignment
- Text Detection: Word-level text box extraction
- Highlighting: Intelligent dilation and area filtering
$3
Key parameters in public/app.js:
`javascript
const SCALE = 3.0; // Rendering DPI (3x = ~300 DPI)
const MAX_SHIFT = 3; // Pixel search radius for alignment
const COLOR_TOLERANCE = 120; // Color difference threshold
const MIN_HIGHLIGHT_AREA = 60; // Minimum area to highlight (pixels)
const MIN_WORD_SIZE = 8; // Minimum word box size (pixels)
const HIGHLIGHT_ALPHA = 0.32; // Highlight transparency
`
š¦ Project Structure
`
pdf-diff-viewer/
āāā src/
ā āāā PDFDiffViewer.js # Main embeddable library
āāā public/
ā āāā index.html # Standalone app interface
ā āāā app.js # AngularJS standalone app
āāā example/
ā āāā index.html # Usage example
āāā bin/
ā āāā cli.js # CLI entry point
āāā server.js # Express server (optional)
āāā package.json
āāā README.md
`
š” Usage Examples
$3
`javascript
const viewer = new PDFDiffViewer('#container');
await viewer.compare(pdfFileA, pdfFileB);
`
$3
`javascript
const viewer = new PDFDiffViewer('#container', {
scale: 2.5,
labelA: 'Version 1',
labelB: 'Version 2',
highlightAlpha: 0.4,
colorTolerance: 100
});
`
$3
`javascript
// Perfect for gray backgrounds (#D9D9D9)
const viewer = new PDFDiffViewer('#container', {
highlightColorA: '#FF1744', // Vibrant red for Doc A changes
highlightColorB: '#2196F3', // Bright blue for Doc B changes
backgroundFillColor: '#D9D9D9', // Match your PDF background
highlightAlpha: 0.4 // Adjust transparency
});
`
Recommended color combinations:
For light backgrounds:
`javascript
// Red vs Blue (high contrast)
{ highlightColorA: '#FF1744', highlightColorB: '#2196F3' }
// Purple vs Orange
{ highlightColorA: '#9C27B0', highlightColorB: '#FF6F00' }
// Pink vs Teal
{ highlightColorA: '#E91E63', highlightColorB: '#00BCD4' }
`
For dark backgrounds:
`javascript
// Bright yellow vs Cyan
{ highlightColorA: '#FFEB3B', highlightColorB: '#00E5FF' }
// Lime vs Magenta
{ highlightColorA: '#CDDC39', highlightColorB: '#E040FB' }
`
$3
`javascript
const viewer = new PDFDiffViewer('#container', {
cropRegions: [
{ page: 1, x: 100, y: 150, width: 400, height: 200 }
]
});
`
$3
`javascript
// Smart alignment is now automatic! No configuration needed
// Handles cases where content shifts across pages
// (e.g., adding text pushes content to next page)
const viewer = new PDFDiffViewer('#container', {
alignmentTolerance: 2, // Search +/- 2 pages for matches (default)
similarityThreshold: 0.3 // Require 30% content similarity (default)
});
const results = await viewer.compare(pdfA, pdfB);
console.log('Page mappings:', results.pageMapping);
// Output: [{ pageA: 1, pageB: 1, similarity: 0.95 },
// { pageA: 2, pageB: 3, similarity: 0.87 }, ...]
`
How it works:
- Automatically detects and handles different page counts
- Extracts text from all pages in both documents
- Uses Jaccard similarity to find best-matching pages
- Shows similarity scores in the results
$3
`javascript
const viewer = new PDFDiffViewer('#container', {
maskRegions: [
{ page: 1, x: 50, y: 30, width: 200, height: 60 } // Ignore date field
]
});
`
$3
`javascript
const bufferA = await fetch('/path/to/doc-a.pdf').then(r => r.arrayBuffer());
const bufferB = await fetch('/path/to/doc-b.pdf').then(r => r.arrayBuffer());
await viewer.compare(bufferA, bufferB);
`
ļæ½ Key Highlights
- Client-Side Processing - All PDF comparison happens in your browser, no server uploads needed
- Zero System Dependencies - No need for GraphicsMagick, ImageMagick, or GhostScript
- Instant Setup - Just open the HTML file in a browser, or run npx pdf-diff-viewer` for the server version