iKit
Guide · 9 min read ·

Comparing Translation Pairs: A Word-Level Diff Workflow (2026)

Reviewing a revised translation? A word-level diff shows the exact words an editor changed inside a paragraph, in any language. Here's the 2026 workflow.

Comparing Translation Pairs: A Word-Level Diff Workflow (2026)

Comparing Translation Pairs: A Word-Level Diff Workflow

A reviewer sends back your Spanish copy with "a few small fixes." You open both versions side by side and every paragraph is a wall of red and green — but only a handful of words really changed. Line-level diff can't tell you which ones. A word-level diff can: it drills inside each changed sentence and highlights just the words an editor touched, in any language. This guide covers the workflow for reviewing translation pairs, including CJK.

TL;DR

  • Line-level diff floods prose with noise; word-level diff shows only edited words.
  • Paste original and revised translation into a diff checker, switch to word mode.
  • CJK text needs Unicode-aware segmentation, not a split on spaces.
  • git diff --word-diff gives inline [-old-]{+new+} markers on versioned files.
  • Run the comparison in-browser so confidential source strings never upload.

Why line-level diff fails on translation pairs

Translated text is prose, and prose breaks the assumptions a line-level diff is built on. The default unit of comparison is the line, so any line that differs by a single character is flagged whole.

The whole line lights up when one word changed

Say an editor changes "rapidly" to "quickly" in a 40-word sentence that sits on one line. To a line-level diff, that line no longer matches its counterpart, so the entire sentence is marked removed and the corrected sentence marked added. You now have to re-read both versions word by word to find the one that moved — exactly the manual work the diff was supposed to save. On a paragraph of marketing copy, that's dozens of "changed" lines hiding a couple of real edits.

Reflowed sentences look like total rewrites

Translations get re-wrapped constantly. A translator fixes one clause, the CAT tool re-flows the segment, and now the line breaks fall in different places than the original export. Line-level diff sees every shifted line as a change even when the words are identical. The signal-to-noise ratio collapses, and reviewers start skimming — which is how a real terminology error slips through.

Bilingual review needs word-precision

Translation review is a bilingual examination of the target against the source. ISO 17100, the international standard for translation services, defines this revision step as a mandatory second-linguist check for accuracy and suitability. That reviewer's job is to justify each individual change, not to eyeball two blocks of text. Word-level granularity is what makes their edits auditable: "here is the exact word I replaced, and here is why."

How to diff two translations word by word

The core move is to compare the two target versions — not source against target — at word granularity.

Paste both versions into a word-level diff

Put the original translation in the left pane and the revised translation in the right pane of a diff checker, then switch the mode from line to word. iKit's Diff Checker does this in the browser: it segments each side into words, aligns them, and highlights only the tokens that were inserted, deleted, or replaced. A one-word fix shows up as one changed word, not one changed paragraph.

Reading added, removed, and moved words

Word-level output uses two markers you'll see everywhere, including in git. Removed words are wrapped one way and added words another. In git's plain word-diff format the convention is [-removed-] for deletions and {+added+} for insertions:

Se conecta [-rápidamente-]{+de inmediato+} al
servidor y {+luego+} descarga la respuesta.

Read that as: "rápidamente" was removed, "de inmediato" and "luego" were added. Everything unmarked is untouched. This is the whole value proposition — your eye goes straight to the three tokens that matter.

git diff --word-diff for versioned .po and .xliff files

Most localization files — gettext .po, XLIFF, JSON message catalogs — live in git. You don't need a separate tool to review a translation commit: git refines any changed hunk word by word on request. Per the official git diff-options documentation, --word-diff computes the normal line diff first, then splits each changed region on whitespace:

git diff --word-diff HEAD~1 -- locale/es/messages.po

For character-level detail — essential when a translator changed a single accent or a CJK character — add a regex that treats every character as a token:

git diff --word-diff --word-diff-regex=. messages.po

That drops the granularity all the way down so café versus cafe shows the missing accent rather than flagging the whole word.

How to word-diff Chinese, Japanese, and Korean text

Everything above assumes words are separated by spaces. For roughly half the world's writing that assumption is wrong, and a diff tool that splits on spaces produces useless output.

Why splitting on spaces breaks for CJK

Chinese, Japanese, Thai, Lao, Khmer, and others write continuous text with no spaces between words. Split 吾輩は猫である on whitespace and you get one giant token — the whole sentence. A word-level diff then degrades back to comparing entire sentences, which is the very problem you were trying to escape. Any edit inside the string marks the complete segment as changed.

Intl.Segmenter and Unicode word boundaries

Real segmentation needs the rules in Unicode Standard Annex #29, the specification for finding grapheme, word, and sentence boundaries across scripts. As UAX #29 itself notes, reliable word boundaries in Thai, Lao, Chinese, and Japanese require dictionary lookup, not simple character rules. Modern browsers expose exactly this through Intl.Segmenter, which reached Baseline "newly available" status across all major engines in 2024 per MDN:

const seg = new Intl.Segmenter("ja-JP", {
  granularity: "word",
});
const words = [...seg.segment("吾輩は猫である")]
  .filter((s) => s.isWordLike)
  .map((s) => s.segment);
// ["吾輩", "は", "猫", "で", "ある"]

A browser diff tool built on this splits 吾輩は猫である into real words, so changing to highlights one character instead of the whole line. The isWordLike flag lets it drop pure punctuation and whitespace from the comparison.

Setting the right locale for the diff

Segmentation is locale-sensitive, so tell the tool which language it's reading. Japanese and Chinese share Han characters but segment differently; ja-JP and zh-CN produce different word boundaries for the same glyphs. When a diff tool lets you pick a locale, match it to the target language of the translation. If you can't set a locale, fall back to character-level diff — noisier, but it never merges a whole sentence into one token.

A word-level diff workflow for translation QA

Put the pieces together into a repeatable review pass. A good automated QA order is to catch structural errors first, then read for meaning — the same logic applies to diffing versions.

Step 1: Freeze the source, compare target versions

You're reviewing what the editor changed, so diff target-old against target-new, not source against target. Keep the source string visible in a third pane or your CAT editor for context, but the diff itself compares the two translations. This isolates the editor's decisions from the original translator's.

Step 2: Separate real edits from whitespace noise

Translators and tools add or collapse spaces constantly, and a naive diff flags every one. Turn on "ignore whitespace" so a re-wrapped segment or a doubled space doesn't drown out a genuine word change. Then scan the remaining highlighted tokens — those are the edits worth justifying. Watch specifically for:

  • Terminology swaps that violate the glossary (a changed product name, a switched register).
  • Number and placeholder changes — {count}, %s, or a currency figure edited by accident.
  • Punctuation that differs between locales, like the full-width comma versus ,.
  • Words silently dropped, which a word-level diff shows as a deletion with no matching insertion.

Step 3: Feed changes back into the glossary and memory

Once you accept an edit, it shouldn't stay trapped in one file. In a managed workflow, an approved revision updates the corresponding entry in the translation memory so the same string is corrected everywhere. A word-level diff is what makes that clean: because you can see the precise before/after token, you can update the glossary or TM with the exact term rather than re-typing a whole segment and risking a new typo.

The same three-pane habit works outside CAT tools. If you draft localized copy in Markdown, iKit's Markdown Editor gives you a clean plain-text source to diff, and the Word & Character Counter confirms a translation still fits a length budget — useful when the target language runs long and a UI string has a hard character cap.

Diff granularity at a glance

Not every review needs the finest granularity. Pick the level that matches what you're comparing.

Granularity Best for Weakness
Line Code, config, structured catalogs Floods prose with false changes
Word Prose, revised translations, docs Needs real segmentation for CJK
Character Accents, CJK glyphs, single-char fixes Noisiest; hard to skim on long text

For most translation pairs, word-level is the sweet spot; drop to character-level only when you're chasing a single accent or ideograph, and use line-level when you're reviewing the structure of the catalog file rather than the copy inside it.

References

Related on iKit

Related posts