Skip to main content

Convert PO (gettext) to JSON (i18next) — msgid becomes the key, msgstr becomes the value

Free CLI to convert gettext .po files to i18next-style JSON bundles. Uses msgid as the key, msgstr as the value, and produces deterministic, alphabetized output.

Free CLI — convert po files to i18next:

npm install -g @i18n-agent/i18n-convert
Need to translate, not just convert? Try i18nagent.ai MCP →

Gettext PO files are the lingua franca of legacy server-side localization — Python's gettext, PHP's gettext, Django, WordPress, and countless Ruby on Rails projects sit on top of them. Modern web applications, by contrast, have largely standardized on i18next-style JSON for runtime translation lookups. Migrating from a PO-based backend to a JavaScript or TypeScript front end usually means writing the same conversion twice: once for a one-time backfill, and again every time the translation files change.

i18n-convert reads each msgid/msgstr pair in the PO file and emits a JSON object whose keys are the msgid source strings and whose values are the msgstr translations. The PO header pseudo-entry (the one whose msgid is the empty string and which carries Content-Type and Language metadata) is correctly skipped rather than emitted as a "" key. Keys are sorted alphabetically for deterministic, review-friendly diffs. Because msgid strings often contain format placeholders like %s, the converter passes them through verbatim — your runtime, not the converter, decides how to interpret them. A data-loss warning fires for the discarded PO header metadata, requiring --force to acknowledge that target-side JSON cannot carry the Language header alongside the translations.

Command

i18n-convert simple.po --to i18next --force -o messages.json

Input

# Simple PO file for testing
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de\n"
"MIME-Version: 1.0\n"

msgid "Hello"
msgstr "Hallo"

msgid "Goodbye"
msgstr "Auf Wiedersehen"

msgid "Welcome to %s"
msgstr "Willkommen bei %s"

Output

{
  "Goodbye": "Auf Wiedersehen",
  "Hello": "Hallo",
  "Welcome to %s": "Willkommen bei %s"
}

Related conversions