✳ OMNIVIEWER

Drop two files. See exactly what changed.

Drop A · drop B · nothing leaves this page

safe · secure · no server · works offline · fast

…or paste a file you copied in Finder, or just start typing at the cursor.

Try it: two versions of the same JSON config · Try it: the same PNG, before and after a hidden message

↓ scroll for about & FAQ

Preview

Drop a CSV file, or use the file picker.

A diff checker that also reads bytes

Most online diff tools take two blobs of text and colour the lines that differ. That is the common case and OmniViewer does it properly — side‑by‑side or unified, word‑level highlighting inside a changed line, and the ignore‑whitespace, ignore‑case and ignore‑blank‑line switches that stop a re‑indentation from drowning the one edit you were looking for. It also emits a real unified .patch, so what you see is something git apply will accept rather than a screenshot.

But plenty of files that need comparing are not text, and that is the half the web usually leaves out. Two firmware images. A photo before and after a tool touched it. A binary you built twice, wondering whether the build is reproducible. For those the BIN tab puts both files in a hex view side by side and lights every byte that differs — and then answers the question a hex dump on its own never does: what kind of change was this?

Which bits changed, not just which bytes

A byte can differ in eight ways at once, and which of the eight moved is information. OmniViewer counts the Hamming distance — the number of differing bits, not bytes — and breaks it down by bit position. That histogram makes a whole class of edit legible on sight.

Every changed byte differing in exactly one bit, and always the lowest one, is least‑significant‑bit steganography: data hidden in the quietest bit of many samples, where it changes a pixel or an audio sample by an amount nobody can perceive. A re‑encode does not look like that — it rewrites whole bytes across every plane. Neither does a metadata edit, which moves a contiguous run rather than a scatter. You can tell all three apart from one bar chart.

The same reading applies to file size, and it is the stronger clue of the two. If two files differ but are byte‑for‑byte the same length, almost nothing benign explains it: a re‑save picks its own size. An identical size plus a scatter of changed bytes means something was rewritten in place, inside the existing structure — which is exactly what OmniViewer’s own /png/secret does when it hides a message in a PNG’s compression choices without moving a single pixel. The demo pair on this page is that: the same image twice, identical in size and in every pixel, differing in 1,877 bytes.

Two files that do not fit in memory

A byte comparison is the one comparison that can be done honestly in constant memory, so OmniViewer does. Both files are read in lockstep, 4 MB at a time; each pair of blocks is folded into counters, a list of differing regions and a fixed‑size density map, and then discarded. Peak memory is two blocks whatever the files weigh, so two 20 GB images compare on a laptop. The hex view is windowed on top of that — it slices only the rows on screen out of each file — which is the same technique the rest of OmniViewer uses to open files far larger than RAM.

The text comparison is bounded instead, and says so when it bites: two multi‑gigabyte files cannot both be held as strings and diffed line by line, so TXT reads a capped prefix of each. Within that it is not the naive algorithm most web tools ship. A quadratic longest‑common‑subsequence table needs a cell per pair of lines, which is why so many diff pages give up in the low thousands. Myers’ O(ND) algorithm walks the edit graph by edit distance in linear space, so the cost tracks how different two files are rather than how big they are — and two 200,000‑line files that differ in ten places diff instantly. The full story is in how to diff two huge files in a browser.

What each tab does, in plain terms

Comparing two JSON exports is the most common reason people arrive here, and it is the case where choosing between the two tabs matters most — a byte comparison is offset‑aligned, so one inserted record shifts everything after it, while the line diff finds its own alignment and costs more. That trade‑off, with a benchmark taking the byte comparison to 6.4 GB a side, is written up in how to diff two JSON files.

OmniViewer opens every file format; the diff route is the one that takes two of them at once, powered by the same viewing engine as fastjsonviewer.com and hugecsv.com.

FAQ

Are my files uploaded anywhere?

No. OmniViewer is a static page with no server-side processing. Both files are read directly by your browser and compared in a Web Worker on your own machine. Nothing is sent anywhere, which is the main reason to use it for a file you would not paste into a website — a config with credentials in it, an unreleased binary, a private document.

How large can the two files be?

The binary comparison has no practical limit. Both files are streamed in lockstep in 4 MB blocks and each block is discarded once it has been counted, so peak memory is two blocks no matter how large the files are — two multi-gigabyte files compare fine. The text comparison is bounded, because line-diffing two files means holding both as text: it reads the first 16 MB of each side and tells you when it truncated. The binary tab still covers every byte of both files in that case.

What does "ignore whitespace" actually ignore?

It collapses runs of spaces and tabs to a single space and drops leading and trailing whitespace before comparing, so a re-indentation, a converted tab or a stray trailing space is no longer a difference. It deliberately does not remove whitespace entirely — that would make "a b" equal "ab", which is a different and wrong claim. The normalisation applies only to the comparison: every row still shows the real text of the file, indentation and all.

Can I get a patch file out of it?

Yes. The TXT tab emits a real unified diff — the format git and patch read, with --- / +++ headers and @@ hunk ranges, three lines of context, and overlapping hunks merged. Copy it to the clipboard or download it as a .patch. It is generated from the same comparison you are looking at, under whichever ignore options are switched on.

What is the bit-plane histogram for?

It shows which of the eight bits in a byte actually changed, and how often. The shape of that chart identifies the kind of edit. Every changed byte differing in exactly one bit, always bit 0, is least-significant-bit steganography — data hidden in the quietest bit of many samples. Changes spread across all eight planes mean whole values were rewritten. A single higher plane means one bit plane was replaced. A byte count alone cannot tell those apart; a bit count can.

Two files are the same size but not identical. What does that mean?

Almost always that one was edited in place rather than regenerated. Re-encoding or re-saving a file picks its own length and essentially never lands on exactly the original, so an identical size with differing bytes points at something rewritten inside the existing structure: a metadata field overwritten, a compression choice swapped, or a payload hidden in space the format already had. OmniViewer says so explicitly when it sees that combination.

Why is my diff slower on two completely unrelated files?

The Myers algorithm costs time proportional to the number of differences, so it is nearly instant on two similar files and most expensive on two that share nothing. There is a work budget: past it, that region is reported as a wholesale replacement rather than spending unbounded time proving two unrelated files have nothing in common — which is the honest answer anyway.

Can I compare a text file against a binary one?

Yes, though the useful answer will be on the BIN tab. Both tabs accept any two files: TXT decodes both as UTF-8 and line-diffs them, which is meaningful only if they really are text, while BIN compares raw bytes and works on anything. The two tabs run on the same pair, so you can switch between them without re-dropping.