The guard trips when the two sides together exceed 400,000 lines. The comparison stops with the actual line count in the message instead of hanging; streaming for very large files is a later release
Intra-line word diff
2000 characters
src/engines/text/textDiff.ts
Word-level marking is quadratic, so it is skipped on longer lines — the line still shows as modified
Fold threshold
8 lines
src/engines/text/textDiff.ts
Unchanged runs longer than this collapse
Fold context
3 lines
src/engines/text/textDiff.ts
Kept at each end of a folded run
Pairing similarity
0.34
src/engines/text/textDiff.ts
Below it a delete and an add are not paired into one modified row
Row height
20 px
--dd-row-height
Fixed, so the virtualiser needs no measurement pass
Larger images are downscaled before comparing, with a normalisation note saying so
Zoom ceiling
400%
src/renderer/src/lib/imageZoom.ts
Zoom hard floor
1%
src/renderer/src/lib/imageZoom.ts
At 1% a 4096 px canvas is 41 px wide — nothing below that is a view of anything
Zoom stops
5, 10, 25, 33, 50, 66, 100, 150, 200, 300, 400%
src/renderer/src/lib/imageZoom.ts
The ladder the − / + buttons walk. The current fit is spliced in at runtime, so stepping out of a fitted view always passes back through it
Fit
capped at 100%
src/renderer/src/lib/imageZoom.ts
"Fit" never magnifies — a 16 × 16 favicon filling the window is not what anyone means by fitting it
The zoom floor is relative to fit, not flat: 25% of a 4000 px pair is 2000 px
of pane in a 900 px stage, so a flat minimum would leave a view of both images
unreachable however many times you clicked.
From the project's own performance budgets, measured 2026-08-12 on the owner's
Mac against an unpackaged build unless the row says otherwise. Budgets were set
first; these are what the app actually did.
Metric
Budget
Measured
Cold start → interactive Compare screen
< 1.5 s
294 ms
✅
1 MB text pair, end to end
< 300 ms
140 ms
✅
100k-line text pair
< 3 s, UI responsive
195 ms
✅
Folder scan + status, 10k files
< 5 s warm
820 ms for 3k × 2 (~2.7 s extrapolated)
✅
4K PNG pair, pixel diff
< 800 ms
23 ms (pixel pass; decode excluded)
✅
Scroll on a 50k-row result
60 fps
60 fps — median frame 16.7 ms, p95 16.7 ms, 52 rows in the DOM
✅
Idle RAM, one comparison open
< 300 MB
592 MB across all processes / 204 MB renderer alone, packaged
The scroll figure is a real instrument rather than an assertion shaped like one: it
samples requestAnimationFrame deltas over 120 frames while the diff is actually
scrolling, and prints the distribution. Its automated assertion is deliberately a
floor, not the budget — frame pacing on a shared CI box is not the owner's
machine, and a test that fails because another process got the CPU teaches nothing.
The number worth reading is the printed p95; the assertion only catches a collapse,
such as a virtualiser that started measuring every row.