Flutter's Application Resource Bundle (.arb) is a JSON dialect with a particular convention: every translation key has a sibling metadata key prefixed with @, and the bundle as a whole carries @@locale and other @@-prefixed root fields. This is great for a Flutter-only world — flutter_localizations knows exactly how to read it — but the moment you also ship a web client or a marketing site that consumes the same strings, the ARB format becomes an obstacle. Web i18n libraries (i18next, react-intl, lingui) want plain JSON with values, not the ARB metadata sidecars.
i18n-convert parses the ARB file, drops every @@-prefixed root metadata key (such as @@locale, @@last_modified), drops every @key-prefixed per-entry metadata sidecar, and emits a clean i18next-style JSON object with only the user-facing key-value pairs. The remaining entries are sorted alphabetically for deterministic, review-friendly diffs. The @@locale field is not lost — it is read to determine the target language, which downstream tooling can use; it is only the JSON output shape that omits it, because i18next-style bundles are single-locale by convention and the locale is encoded in the filename instead. Placeholder syntax such as Flutter's ICU-style {count} passes through verbatim for the runtime to handle.
Command
i18n-convert simple.arb --to i18next -o messages.json
Input
{
"@@locale": "en",
"appTitle": "My App",
"welcomeMessage": "Welcome to our app!",
"goodbye": "Goodbye"
}
Output
{
"appTitle": "My App",
"goodbye": "Goodbye",
"welcomeMessage": "Welcome to our app!"
}