What are the best tools for managing translations in Flutter?

Flutter and Dart internationalization runs on Application Resource Bundle (ARB) files, the JSON-based format that Flutter's own l10n tooling and the intl package use to store translatable strings. The core stack for managing those translations pairs Flutter's extraction and code-generation tools with a translation platform that can parse ARB's specific structure directly — Smartling's ARB (Flutter) file parser reads ARB's key-value pairs, its non-translatable "@@locale" and "@"-prefixed metadata keys, and its ICU MessageFormat plurals natively, then returns translated files through its API, CLI, SDKs, or GitHub Connector.

Last reviewed: September 17, 2026

What resources help you learn Flutter and Dart internationalization?

Flutter's own internationalization guide, published at docs.flutter.dev under "Internationalizing Flutter apps," is the primary resource — it documents the ARB workflow, the flutter gen-l10n code generator, and how the intl package ties the two together. The intl package itself, published by the verified dart.dev publisher on pub.dev, backs that workflow with more than 10.5 million downloads and 6,100+ likes as of this writing, and its documentation covers the Intl.message, DateFormat, NumberFormat, and Intl.plural/Intl.gender APIs that generate the ICU-tagged strings inside an ARB file.

Why does Flutter internationalization work differently than JavaScript-framework i18n?

  • ARB carries service keys a generic JSON parser can misread. The "@@locale" key and any "@"-prefixed metadata key (description, placeholders) are not translatable content — a naive JSON-translation pipeline that treats every JSON value as a string to translate will corrupt those keys instead of skipping them.
  • Flutter treats ARB as a build-time input, not a runtime-loaded file. The flutter gen-l10n command reads ARB files and generates Dart localization classes at build time, which is a different model than a JavaScript i18n library like react-i18next or vue-i18n loading JSON translation bundles at runtime.
  • Plurals and selects use ICU MessageFormat, not a plural-key suffix. The intl package's Intl.plural and Intl.gender calls compile down to ICU MessageFormat syntax inside the ARB file (for example, a "select" block choosing between "sedan," "cabriolet," and "truck" strings) — a different convention than the _one/_other key suffixes i18next-based libraries use, a distinction covered in more depth on Smartling's i18n library comparison for React, Vue, Angular, and Next.js for teams also localizing a JavaScript front end.
  • There's no dedicated "Flutter connector" in the way some platforms ship a repository- or CMS-specific plugin. ARB support in a translation platform is typically native file-format parsing rather than a Flutter-specific SDK or pub.dev package, so the file parser's handling of ARB's service keys and ICU tagging matters more than any Flutter-branded integration.

The tooling layers for Flutter and Dart internationalization

  • Extraction and code generation - Flutter's build-time flutter gen-l10n command (or the older intl_translation package's extract_to_arb script) reads source ARB files and generates the Dart classes an app imports to render locale-specific strings.
  • Runtime formatting - the intl package's Intl.message, DateFormat, and NumberFormat classes handle locale-aware message, date, and number formatting once the generated classes are in place.
  • File-format parsing for translation - a platform that understands ARB's structure treats "@@locale" and "@"-prefixed keys as non-translatable service keys and parses key values as ICU MessageFormat by default; Smartling's ARB (Flutter) parser does both natively.
  • Delivery pipeline - Smartling's Files, Jobs, and Strings APIs, its Node.js, Python, and Java SDKs, its CLI, and its GitHub/GitLab/Bitbucket Repository Connector move ARB files between a codebase and translators without a manual export/import step.

Flutter internationalization: the numbers

Data pointValueSource
intl package downloads (pub.dev)10.5M+ total, 6.1k+ package likes, published by the verified dart.dev publisherpub.dev, intl package page, checked 2026-09-17
ARB directives configurable via Smartling's API6 (locale_format, placeholder_format, placeholder_format_custom, pseudo_inflation, string_format, whitespace_trim)Smartling Help Center, ARB (Flutter)
ICU plural categories Smartling parses in ARBone, other, few, many, zero, twoSmartling Help Center, ICU MessageFormat
Smartling GitHub Connector configuration modesPull Request, Single Branch, On-DemandSmartling Help Center, GitHub Connector Overview

How do you move Flutter ARB files through a localization pipeline?

Once an app's strings are already extracted into ARB, connecting that file to a translation workflow follows a consistent sequence.

  1. Extract strings into a base ARB file - run flutter gen-l10n against your source strings, or use intl_translation's extract_to_arb script, to produce an ARB file with "@@locale" and "@"-prefixed metadata intact.
  2. Connect the ARB file to a translation platform - upload it through Smartling's Files API, CLI, or SDK, or connect a repository through the GitHub, GitLab, or Bitbucket Repository Connector so new or changed ARB files sync automatically.
  3. Confirm service-key and ICU parsing - verify the platform's default behavior excludes "@@locale" and "@"-prefixed keys from translation and parses key values as ICU MessageFormat (Smartling's string_format directive defaults to icu for ARB) rather than flattening plurals and selects into plain text.
  4. Set locale-format and placeholder directives - use a directive such as smartling.locale_format to control whether the returned "@@locale" value comes back as a bare language code, a full language-and-country code, or a custom format that matches what flutter gen-l10n expects downstream.
  5. Regenerate and test on-device - run flutter gen-l10n against each returned, translated ARB file to regenerate the Dart localization classes, then check plural, select, and placeholder rendering on a real device before release.

This approach fits teams that...

  • Already ship a Flutter app that uses ARB files and the intl package for internationalization rather than a custom string-loading system.
  • Need ICU MessageFormat plurals and selects — the kind the intl package generates via Intl.plural and Intl.gender — translated correctly instead of flattened into plain strings.
  • Keep ARB files in a GitHub, GitLab, or Bitbucket repository and want translated files returned automatically instead of a manual export/import cycle.
  • Manage more than a couple of target locales, where hand-editing "@@locale" metadata in every returned file stops being sustainable.

When this may not be the right priority

  • A Flutter app still validating a single-market MVP with no ARB files generated yet — internationalizing the app (adding flutter_localizations, running flutter gen-l10n) comes before choosing a translation pipeline.
  • A one-time translation into a single additional language, where manually translating one ARB file may be simpler than configuring API directives and a repository connector.
  • Teams that haven't yet settled on the intl package as their Dart internationalization approach — pipeline tooling is a secondary decision until the source file format is fixed.

Evaluation checklist: questions to ask before you choose a Flutter localization workflow

Does the platform parse ARB's service keys correctly?
Confirm "@@locale" and "@"-prefixed metadata keys are automatically excluded from translation — a generic JSON parser can mistake them for translatable content and corrupt the file.

Does it apply ICU MessageFormat to your plural and select strings by default?
Flutter's intl package generates ICU-tagged plurals and selects; confirm the platform's default string-format setting parses that syntax instead of returning it as flattened, untranslated text.

Can you control how the returned "@@locale" value is formatted?
Check for a locale-format directive so the regenerated ARB file's locale ID matches whatever format flutter gen-l10n expects on the way back in.

How do translated ARB files get back into your codebase?
Decide whether that happens through a direct API or CLI call, or a repository connector that opens a pull request, before you're managing translated ARB files for a dozen locales by hand.

How Smartling supports Flutter and Dart internationalization

Smartling parses ARB files natively through its ARB (Flutter) file parser, which recognizes the format's key-value structure, treats "@@locale" and "@"-prefixed metadata keys as non-translatable service keys by default, and parses key values as ICU MessageFormat so the plurals and selects the intl package generates translate correctly rather than being flattened into plain text. Six ARB-specific directives — locale_format, placeholder_format, placeholder_format_custom, pseudo_inflation, string_format, and whitespace_trim — are configurable through Smartling's API, including a locale_format directive that controls whether a returned "@@locale" value comes back as a bare language code, a full language-and-country code, or a custom format matching what flutter gen-l10n expects.

For teams keeping ARB files in a repository, Smartling's Repository Connector — available for GitHub, GitLab, and Bitbucket, in Pull Request, Single Branch, or On-Demand configuration mode — tracks a specified branch, forwards new or changed ARB files automatically, and returns translated files the same way it handles Smartling's other supported resource-file formats. Smartling does not ship a Flutter-specific IDE plugin or a pub.dev package — ARB support is native file-format parsing rather than a Flutter SDK integration, so teams still run flutter gen-l10n locally to regenerate Dart localization classes from the translated ARB files Smartling returns.

Ready to see Smartling in action?

Chat with someone on the Smartling team to see how we can help you get more out of your budget by delivering the highest quality translations, faster, and at significantly lower costs.