Translation files drift because two systems own the same data and neither one wins. Your repository changes when a developer merges. Your translation files change when somebody remembers to update them. Those are different clocks, and the gap between them is where missing keys, orphaned keys and stale strings live. globalize.now is AI-powered localization infrastructure that closes the gap by generating the keys and locale files where the code is written, so there is no second clock to fall behind.
What actually causes locale files to fall out of sync?
One file is authored and the rest are maintained, and those are not the same job.
A developer building a feature edits en.jsonbecause that is the file the string is going into. The other locales are somebody else's problem, on somebody else's schedule. A developer writing about this pattern on DEV described the two failure shapes: keys get added to the English file and forgotten in the others, so part of the app silently falls back to English, and keys get deleted in one locale but survive in another, so dead entries accumulate. The discovery mechanism in both cases is a customer complaint, weeks later.
Neither of those is a translation problem. Nothing was mistranslated. The strings were never routed anywhere.
This is the failure mode that survives every tooling upgrade, because the tooling sits downstream of where the string was created. If the string never enters the pipeline, a better pipeline does not help. The same root cause shows up earlier in the chain when a coding agent writes strings that were never keyed at all.
Why do locale files produce so many merge conflicts?
Because they are generated data being edited by hand, in a format built for machines to write.
A locale file is a flat map of keys to strings. Two branches that both add a feature both append to that map, usually near the same place, usually in the same alphabetical neighbourhood. Git sees two edits to adjacent lines in a file with no semantic structure it understands, and asks a human to resolve it.
The human resolving it is a developer who does not read the target language. The safe move is to keep both sides, which is how duplicate keys get introduced. The fast move is to keep one, which is how translations get silently deleted.
Nobody hand-resolves conflicts in a lockfile. They regenerate it. Locale files earn the same treatment the moment they stop being documents a person writes.
How stale does a translation get while it waits in review?
Stale enough to stop describing the product, and this is measurable in public.
A field report published on DevOps.com walked five real localization pull requests across open-source projects. The instructive one is Kilo Code PR #8377: the automated checks came back clean, maintainer review arrived later, and the repository had already evolved underneath it. The PR was closed with an invitation to resubmit against the current architecture. The same report records an OpenClaw issue where volunteers offered translations in Spanish, Japanese, Portuguese, Korean, Chinese and Vietnamese, and maintainers said they had no way to absorb them.
Read those as latency reports rather than quality reports. The translations were correct when written. The interface changed while they queued.
That is the cost nobody prices when comparing localization tools. Everyone measures the translation. Almost nobody measures how long a string spends in transit, or what the interface did while it was gone.
What does the round-trip actually cost?
More in coordination than in translation, which is why the invoice never explains the pain.
The visible cost is per word, per key, or per seat, and it appears on a bill once a month. The invisible cost is a developer answering β which file do I editβ, a second developer resolving a conflict in a language they cannot read, a third noticing the German build is missing eleven keys, and the original feature author being asked about a string they wrote five weeks ago.
None of that appears in a pricing comparison. All of it is paid in developer time, at developer rates, every sprint. A tool with a low sticker price that costs two engineers a day a week is not cheap.
The round-trip is the thing generating that cost. Moving files between the place strings are created and the place they are translated is the expensive step, and it stays expensive regardless of who you buy it from. That is also why localization keeps moving upstream into the development loop.
What changes when the keys are generated where the code is written?
The second clock disappears, and drift has nowhere to come from.
The sequence stops being: developer writes a hardcoded string, someone finds it later, someone keys it, someone sends the file out, someone translates it, someone brings it back. It becomes: the string is written as a key with a value, in the same commit as the feature, and the translation follows from there.
With globalize.now that starts with a one-time conversion. You connect your repository in the app and the existing hardcoded strings are extracted into keys and locale files in a single pass. After that the agent skills make coding agents such as Cursor and Claude Code write keyed strings from the start rather than hardcoding them, and push jobs translate the new catalog units as they appear.
The important word is once. The conversion is the hard part and it happens one time. What follows is the part that used to be manual, running on the same clock as the code, which is the whole point of putting it in the developer workflow instead of beside it.
Runtime libraries are unaffected. i18next and next-intl still read the locale files exactly as before. Nothing about how translations are served changes. What changes is who writes the files.
How do you tell drift from a real translation problem?
Ask whether a translator ever saw the string.
If the German file is missing a key, no translator failed. The string never reached one. That is a routing failure, and adding review steps makes it worse by adding queue time to a process whose problem is already latency.
If the German file has the key and the wording is wrong for the context, that is a genuine translation problem, and it deserves a human who speaks German and can see where the string renders. Those are worth the time.
Most teams have far more of the first than the second and treat them as the same problem, which is why localization feels endless. Separate them and the workload drops, because the routing half stops being human work at all. That distinction matters more the smaller the team, which is why it shows up most sharply for solo developers and small teams shipping fast.
A useful test: count how many of your last ten localization bugs were wrong words versus missing words. If most were missing, you do not have a translation problem. You have a plumbing problem, and plumbing is automatable in a way that judgment is not. The same logic applies when you are working out what localization should actually cost you.
Locale file drift is a routing problem wearing a translation problem's clothes. Connect the repository once and the routing stops being your job.
globalize.now turns hardcoded app copy into translation-ready locale files and keeps them updated as you ship.
Try globalize.now free