Home / Blog / Guides
Guides

Locale Codes and Language Codes: ISO 639 and BCP 47 Explained

Understand the difference between language codes and locale codes, how BCP 47 works, which codes to use for en-US, pt-BR or zh-Hant, and how formats differ by platform.

WordBeam Team
Oct 15, 2026 · 5 min read
Locale Codes and Language Codes: ISO 639 and BCP 47 Explained

A language code identifies a language (for example en, de, fr), while a locale code adds a region, script or variant (for example en-US, de-CH, zh-Hant-TW). Locale codes follow the BCP 47 standard, which builds on ISO 639 for languages, ISO 15924 for scripts and ISO 3166-1 for regions. Using the right code decides which translation, date format and currency a user sees.

If your app, website or translation files mix up "en_US", "en-us" and "eng", you will eventually ship the wrong text to the wrong market. This guide explains how locale codes work, shows the most common ones, and lists the format differences between platforms.

Language Codes vs Locale Codes

A language code says which language the content is in. A locale code says how that language is used in a specific place. English in the United States and English in the United Kingdom share a language code (en) but use different spelling, date order and currency, so they have different locales (en-US and en-GB). This is the core difference behind internationalization vs localization: developers prepare software to support many locales, and localization fills each locale with the right content.

The Standards Behind Locale Codes

Most modern systems rely on BCP 47, the "language tag" standard explained in the W3C article Language tags in HTML and XML. A tag is built from subtags, always in the same order: language, optional script, optional region, optional variant.

Part Standard Example Notes
Language ISO 639-1 (two letters), ISO 639-2/3 (three letters) de, fra, yue Use the two-letter code when one exists
Script ISO 15924 (four letters) Latn, Cyrl, Hans, Hant Needed when one language has several scripts
Region ISO 3166-1 alpha-2, or UN M.49 numbers US, BR, 419 es-419 means Latin American Spanish
Variant IANA registry 1996, valencia Rare, for orthography or dialect

So zh-Hant-TW reads as Chinese, Traditional script, Taiwan, and sr-Latn-RS as Serbian written in Latin script in Serbia.

Common Locale Codes for Translation Projects

Locale code Language and region Why it matters
en-US / en-GB English (United States / United Kingdom) Spelling, dates (MM/DD vs DD/MM), currency
de-DE / de-AT / de-CH German (Germany / Austria / Switzerland) Swiss German does not use the letter ß
fr-FR / fr-CA French (France / Canada) Different vocabulary and legal requirements
es-ES / es-MX / es-419 Spanish (Spain / Mexico / Latin America) Vocabulary and formal address differ
pt-BR / pt-PT Portuguese (Brazil / Portugal) Noticeable differences in grammar and terms
zh-Hans / zh-Hant Chinese (Simplified / Traditional) Different scripts, not just regions
ar-SA / ar-EG Arabic (Saudi Arabia / Egypt) Right-to-left layout and regional dialect
ja-JP Japanese (Japan) Date, name order and no spaces between words

Locale Code Formats by Platform

The same locale is written differently depending on the system. This is the most common source of broken language switchers and missing translations.

Platform Portuguese (Brazil) Separator and case
BCP 47, HTML lang, browsers pt-BR Hyphen, region uppercase
POSIX, Linux, gettext PO files pt_BR.UTF-8 Underscore, optional encoding
Android resource folders values-pt-rBR Prefix r before the region
iOS and macOS pt-BR (folders use pt-BR.lproj) Hyphen
Flutter ARB files app_pt_BR.arb Underscore in file names

Platform guides such as our articles on Android localization, iOS localization and Flutter localization with ARB files show where each format is used.

Common Mistakes With Locale Codes

  • Using the country as the language. "us", "gb" or "jp" are country codes. The language code for Japanese is ja, not jp.
  • Using deprecated codes. Old tags such as iw (Hebrew), in (Indonesian) and ji (Yiddish) were replaced by he, id and yi.
  • Mixing separators. Convert between en_US and en-US in one place, not across the codebase.
  • Ignoring fallback. If de-AT is missing, the app should fall back to de, then to the default language, never to an empty string.
  • Forgetting scripts. Chinese and Serbian need script information, not only a country.

How to Manage Locale Codes at Scale

Keep one canonical list of locales in a single configuration file, store it in BCP 47 format, and map it to the format each platform needs at build time. Test fallbacks and plural rules with ICU MessageFormat, and check that text is saved correctly with the right character encoding (UTF-8). A translation platform that reads locale codes from your files, such as a software localization workflow connected to your repository, removes most manual mapping errors.

Frequently Asked Questions

What is the difference between en and en-US?

The code en refers to English in general. The code en-US refers to English as used in the United States, with its own spelling, formats and vocabulary.

Should I use hyphens or underscores?

Use hyphens for web and BCP 47 (en-US). Use underscores only where a platform requires them, such as POSIX locales and some resource file names.

Are language codes case sensitive?

BCP 47 tags are case insensitive, but the convention is lowercase language, title case script and uppercase region, for example zh-Hant-TW.

Keep Every Locale Consistent With WordBeam

WordBeam reads locales from your files and repositories, applies translation memory and glossary to each one, and pushes approved translations back without manual copying. Explore the translation management system or start free with 14 days and 10,000 words.