i18n vs l10n: what's the difference?

Internationalization is the engineering work that makes translation possible. Localization is the translation itself. Here is where the line falls and why it matters.

Internationalization (i18n) is the engineering work that makes translation possible. Localization (l10n) is the translation itself. One is done by developers, once per feature; the other is done by translators, once per language.

The distinction sounds academic until a project goes wrong, at which point it becomes the most useful diagnostic you have. Almost every “our translations are broken” problem is really an internationalization problem that surfaced during localization.

Internationalization (i18n)

Internationalization means extracting the translatable text out of your views and into a language file, and replacing it with a function call that references the extracted text. The result is that the text renders as usual in the source language and as a translation in every target language.

ruby
# Before: not internationalized
<h1>Welcome back</h1>
<p>You have <%= count %> unread messages</p>

# After: internationalized
<h1><%= t("dashboard.welcome") %></h1>
<p><%= t("dashboard.unread", count: count) %></p>

That is the visible part. The rest of i18n is the work of removing assumptions your source language let you get away with:

  • Text expands and contracts. German and Finnish run 20–30% longer than English; Chinese and Korean run shorter. A button sized to fit “Save” will not fit “Speichern”.
  • Word order is not universal. Anything built by concatenating fragments — "Deleted " + count + " files" — assumes English syntax and cannot be translated correctly.
  • Plural rules vary wildly. English needs two forms, Polish four, Arabic six. if count == 1 is wrong in French, where the singular covers zero as well.
  • Dates, numbers and currency are locale-dependent. 03/04/2026 is March 4th in the US and April 3rd nearly everywhere else. Decimal separators, thousands separators, and currency symbol placement all move.
  • Sorting is locale-dependent. Swedish sorts ä after z; German sorts it with a. Byte-order sorting is wrong in both.
  • Text has direction. Arabic and Hebrew are right-to-left, which affects layout, icon direction and how mixed-direction strings render.
  • Character encoding must be Unicode throughout, end to end, without exception.

Internationalization also covers the non-linguistic cultural adaptation: units of measurement, address formats, name ordering, phone number formats, paper sizes, and the fact that a red upward arrow means something different in Chinese financial contexts than in Western ones.

This is developer work, it touches a lot of code, and it is occasionally genuinely difficult.

Localization (l10n)

Localization means translating the language file into other languages. Fundamentally it is replacing source text with its translation — simple in principle, and unmanageable at scale without tooling.

The problems arrive with volume rather than complexity:

  • Translating into n languages means coordinating at least n translators.
  • A string that is ambiguous without context generates the same question n times, once per translator, unless there is somewhere shared to answer it.
  • Language files are updated iteratively as the product ships, and keeping n copies in sync by hand does not work.
  • General-purpose translation tools often cannot open technical formats like YAML, JSON, .strings or .po at all.
  • Translators do not have access to your codebase, so they cannot see the context a string appears in.
  • Without a system, “sending files to translators” means email attachments or a shared folder, and the version history lives in someone’s inbox.
  • Verification is hard. Has this character-limited segment been translated within 20 characters in every language? should take seconds to answer, and usually takes a person an afternoon.

Localization is linguistic work, but the difficulty is logistical.

Where the line actually falls

The useful test: could a translator who has never seen your code do this task?

Task Which side
Extracting "Welcome back" into en.yml i18n
Translating "Welcome back" into French l10n
Making a button resize to fit longer text i18n
Deciding whether Speichern or Sichern fits better l10n
Adding plural categories for Polish to the file format i18n
Writing the four Polish plural forms l10n
Formatting a date with the user’s locale i18n
Choosing the right register for a formal-address language l10n
Adding RTL stylesheet support i18n
Translating into Arabic l10n

The pattern: i18n makes the software capable of being in another language. l10n puts it in one.

Why the ordering is not negotiable

You cannot localize what has not been internationalized. There is no file for a translator to open. This sounds obvious and yet it is the single most common way localization projects stall — a team commits to launching in four languages, hires translators, and only then discovers that a third of the interface strings are hard-coded in templates.

A useful sequencing:

  1. Audit. Find every user-facing string. Grep for quoted text in views, then in components, then in server-side messages, emails, PDFs and error pages. The last four are always forgotten.
  2. Extract. Move them into language files with meaningful, hierarchical keys. checkout.payment.card_declined beats error_17.
  3. Fix the assumptions. Concatenation, hard-coded formats, fixed-width layouts, count == 1.
  4. Pseudo-localize. Render the app with accented, expanded placeholder text to reveal anything still hard-coded and any layout that breaks under expansion — before paying for translation.
  5. Then localize. Now translators have a file, and you have confidence the file is complete.

Step 4 is the one teams skip and then regret. Pseudo-localization catches in an afternoon what would otherwise come back as bug reports in a language nobody on the team reads.

The ongoing cost

Internationalization is mostly a one-time project, but not entirely. Every new feature adds strings, and every added string is a small i18n task that can be skipped under deadline pressure. Six months of skipping produces a codebase that is 90% internationalized, which for a translator is indistinguishable from broken.

The teams that stay on top of it automate the check: a lint rule or CI step that fails the build on a hard-coded user-facing string. It is a small investment that converts a slow, invisible regression into an immediate, obvious one.

The localization side has a matching ongoing cost, and this is where a translation management system earns its place — not for the first launch, but for the hundredth week of small, continuous changes. That model is continuous localization: the translation process never ends because the product never stops shipping.

The rest of the numeronyms

You will meet the whole family eventually, and they are all formed the same way — first letter, count of omitted letters, last letter:

Abbreviation Word What it covers
i18n internationalization Making software capable of any language
l10n localization Adapting it to a specific language and region
g11n globalization The umbrella: i18n + l10n + market, legal and commercial strategy
t9n translation The text conversion alone, a subset of l10n
m17n multilingualization Handling several languages simultaneously, not one at a time
a11y accessibility Unrelated to language, same naming convention

In practice engineering teams need i18n and l10n and can ignore the rest. g11n shows up in vendor and enterprise contexts; t9n is useful when you specifically mean “the words” as distinct from the surrounding adaptation work.

The short version

  • i18n = the code can hold any language. Developers. Mostly up front, a little forever.
  • l10n = the code now holds French. Translators. Continuously, per language.
  • Do i18n first, pseudo-localize to prove it worked, then localize.
  • When translations look broken, suspect the internationalization.

Frequently asked questions

What does i18n stand for?
Internationalization, abbreviated by replacing the 18 letters between the first i and the last n. l10n is localization by the same trick, and a11y is accessibility. The numeronym convention exists because these words are long, repetitive to type, and easy to misspell.
Which comes first, i18n or l10n?
Internationalization comes first, and it is a hard ordering rather than a preference. Localization means replacing source text in a language file with its translation, so until the text has been extracted into a language file there is nothing for a translator to work on.
Is i18n a one-time job?
The bulk of it is, but not all. The initial extraction of hard-coded strings is a single large project. After that, every new feature carries a small amount of i18n work, and that ongoing cost is why teams eventually add lint rules or CI checks that fail on a hard-coded user-facing string.
What is g11n, and how does it relate?
Globalization (g11n) is the umbrella term covering both i18n and l10n plus the commercial side — market selection, pricing, legal compliance and support in each region. You will mostly see it in enterprise and vendor contexts; engineering teams rarely need the distinction.

Keep reading

Translate your app without the spreadsheet round-trip

WebTranslateIt reads the file formats and placeholder syntax described on this page, validates them as translators work, and syncs the results straight back into your repository.