Skip to content

i18n key diff

Compare two localization JSON files and list the translation keys missing from each.

Input
JSON B (translated file)
Output

i18n key diff

Paste your base localization file as JSON A and the translated file as JSON B, and this tool flattens both to dot-notation key paths — "nav.home", "errors.notFound" — then reports exactly where they diverge. It's built for the moment a translation file falls behind its source: a new screen ships a handful of strings, someone edits the English copy directly, or a locale was machine-translated months ago and never revisited.

Choose what to report: keys missing from B (added to the source but never translated), keys missing from A (leftover strings a since-removed feature left behind), or both at once. A fourth mode, "untranslated", lists keys that exist in both files with byte-identical values — a strong signal a string was copied across rather than translated, since a real translation only matches the source by coincidence. Nested objects are walked recursively however deep the file goes; arrays are compared as whole values rather than indexed into, the way real localization files treat them.

Output comes as a plain list, one path per line, or as JSON, ready to feed into a script or a CI check that fails a build when translations drift. The tally shows the full picture whichever report mode is selected — how many keys are in A, how many in B, and how many are missing on either side. Invalid JSON is reported by name, quoting the parser's own message, so you know which file to fix.

Everything runs locally in your browser: both files are parsed and compared on your device and never uploaded anywhere, which matters since localization files often carry unreleased feature names and internal terminology before a launch. Use it to review a translator's pull request, audit a locale before a release, or find every string a refactor silently dropped.

FAQ

What counts as a "key" for comparison?
Every leaf value in the JSON, addressed by its full dot path — a nested object like {"nav":{"home":"Home"}} produces the key "nav.home". Arrays are compared as whole values, not split into indexed keys.
What does "untranslated" mode actually detect?
Keys that exist in both files with an identical value. It flags likely-untranslated strings, but a short value that's legitimately the same in both languages (a brand name, a number) will also show up — treat it as a lead to check, not a guaranteed miss.
What happens if a key holds an object in one file and a plain string in the other?
Each side is flattened independently, so that mismatch surfaces naturally: the object's own nested keys appear as missing on the string side, and the string's key appears as missing on the object side.
Is there a limit on file size?
No fixed limit beyond the 10 MB output cap most tools share. Processing runs on your device, so even large catalogs with thousands of keys compare in milliseconds.
Are my localization files uploaded anywhere?
No. Both JSON A and JSON B are parsed and compared entirely in your browser — neither file leaves your device.