Flutter ARB Files: How to Translate Them Without Breaking Metadata or ICU
How Flutter ARB files work, how to protect metadata and ICU syntax, and what teams should know before translating ARB in real apps.
If you are localizing a Flutter app, ARB is not just another JSON file format. It is part of Flutter’s code-generation workflow.
That distinction matters. Application Resource Bundles (ARB) are designed for Flutter’s generated-localization workflow, where translated strings are not just read at runtime, but compiled into a typed Dart interface. That makes ARB more structured than a simple key-value file and more developer-centric than many traditional translation formats.
The result is a format that works especially well for product teams that want type safety, translator metadata, and tight framework integration, but it also comes with rules that generic translation tools often mishandle.
Quick answer ✅
ARB is usually the right default for Flutter because it is part of Flutter's code-generation workflow, not just a storage format for translated strings.
The main mistake is treating ARB like ordinary JSON. Once metadata keys, placeholders, and ICU expressions are mishandled, the localization pipeline becomes harder to trust even if the translated sentences look fine.
ARB is a strong fit when... ✅
- Flutter is the real source of truth for the product
- type safety and generated localization APIs matter
- translator metadata should live close to each key
- the team needs ICU message logic inside the same resource file
It becomes awkward when... ⚠️
- tools treat the file as generic JSON
- placeholder metadata gets stripped or damaged
- the workflow is centered on another runtime, not Flutter
- the team skips review just because generation is type-safe
What makes ARB different from generic JSON?
A standard JSON file is just a map of keys and values. ARB extends this by treating each translation as a resource object. This allows you to attach metadata such as descriptions and placeholders directly to the key.
In a typical ARB workflow, the gen-l10n tool reads these files and generates actual Dart classes, giving you autocomplete and compile-time safety for your strings.
That is the key difference: ARB is not only a storage format. It is part of a code-generation pipeline.
Anatomy of an ARB Resource
An ARB file uses a specific convention: the translation value is stored in a key, and its metadata is stored in a companion key prefixed with an @ symbol.
{ "@@locale": "en", "welcomeMessage": "Hello {name}!", "@welcomeMessage": { "description": "A warm greeting for the user", "placeholders": { "name": { "type": "String", "example": "Dash" } } }}Advanced Logic: Plurals and Genders
One of the strongest arguments for using ARB is its native support for ICU (International Components for Unicode) syntax. This allows you to handle complex linguistic rules for plurals and selections without writing custom if/else logic in your UI.
That connection to ICU is important because many Flutter teams underestimate how much localization logic really belongs in the resource layer rather than in application code. If you want a dedicated explanation of that syntax, our ICU guide goes deeper.
Handling Plurals
Instead of creating multiple keys like itemCount0 and itemCount1, you define a single logic block:
"inboxCount": "{count, plural, =0{No messages} one{1 message} other{{count} messages}}","@inboxCount": { "placeholders": { "count": { "type": "int" } }}Why Flutter developers love ARB
- Type Safety: The generator creates methods like
context.l10n.welcomeMessage(userName), preventing runtime crashes due to missing keys. - Context for Translators: The
@keydescription field is exported to translation tools (like Lokalise or Crowdin), ensuring translators understand where the text appears. - Formatting: Built-in support for
DateTimeandNumberFormatdirectly through placeholders.
ARB vs. Other App Localization Formats
ARB is strongest when your team is deeply invested in Flutter. It is less useful as a universal cross-platform format.
Compared with other common formats:
- Apple String Catalogs provide a similarly first-party experience for Apple platforms
- i18next JSON v4 is more natural for JavaScript and web stacks
- XLIFF is better suited for translator-facing interchange between tools
That means ARB is usually the right source-of-truth format for Flutter apps, even if another format exists elsewhere in the organization’s broader localization pipeline.
Common ARB Workflow Mistakes ⚠️
Treating ARB as plain JSON
Because the files look familiar, teams sometimes edit them with tools that ignore @ metadata keys or damage placeholder definitions. That can break generation or remove translator context.
Forgetting that ICU syntax is code-like
Plural and select expressions are not ordinary prose. Translating them safely requires preserving the logic structure while adapting the human-readable segments.
Skipping runtime review
Even with type-safe generation, teams still need to review how text fits in real widgets, especially for longer languages and smaller device widths.
Why generic JSON translation is risky for ARB
ARB files look familiar enough that teams often run them through whatever JSON tooling is already available.
That is usually where the trouble starts. Once metadata keys, placeholder definitions, or ICU expressions are treated as ordinary text, Flutter’s generation pipeline becomes less predictable and review gets harder.
For teams shipping multilingual Flutter apps continuously, that is exactly the kind of hidden risk that makes a format-aware local workflow worth adopting.
Getting started
To start using ARB files, add flutter_localizations to your pubspec.yaml and enable the generate: true flag. Place your .arb files in the lib/l10n directory, and Flutter will handle the rest.
Check out the Official Flutter Localization Guide for a deep dive into the configuration.
If you are choosing a format for a new Flutter project, ARB is usually the correct default because it fits the framework’s generated-localization story better than generic JSON files do.
Where MetalGlot fits the ARB workflow
ARB files are excellent for Flutter development, but their meta-key structure makes them awkward for tools that only understand raw key-value JSON.
MetalGlot works with that structure directly, which matters when your localization files contain both user-facing copy and machine-important metadata.
- Meta-key awareness: Respect descriptions and placeholder metadata instead of ignoring them.
- ICU-safe handling: Translate the language while preserving plural and select logic.
- Local iteration speed: Review and refine ARB files without routing app strings through external services.
Final take
ARB remains one of the best examples of a localization format that is deeply aligned with a framework. It gives Flutter teams type safety, translator context, and expressive message logic in one workflow.
That strength comes with a clear operational requirement: use tools that understand ARB as more than “just JSON.” When teams do that well, Flutter localization becomes much easier to scale.