i18nfix
v0.1.13
Published
CLI to check/fix i18n JSON files (keys, placeholders, untranslated)
Downloads
1,162
Readme
i18nfix
Write one language. Ship all languages.
A CLI to check, fix, and translate i18n locale files.
Supported formats (common):
- JSON:
.json - YAML:
.yml/.yaml - JS/TS modules exporting an object:
.js/.ts(export default { ... }ormodule.exports = { ... })
What it can do:
- Detect issues: missing keys, extra keys, empty values, possibly-untranslated values, placeholder mismatches
- Fix structure: add missing keys (optionally fill with base), optionally remove extras
- Translate only the problematic keys using an LLM provider (OpenAI / Claude / Gemini / OpenRouter)
Status: MVP / work in progress.
Requirements
- Node.js >= 18
Getting started (integrate into an existing project)
1) Install
npm i -D i18nfix2) Create/update config (Q&A)
npx i18nfix configThis writes i18nfix.config.json in your project root.
3) (Optional) Create new language files
If you currently only have one language and want to scaffold additional languages:
# create ja.ts / fr.ts (skips existing files)
npx i18nfix new --langs fr,jaBy default, i18nfix will follow an existing filename pattern if present (e.g. en.ts → fr.ts).
4) Add npm scripts
Add to your project's package.json:
{
"scripts": {
"i18n:config": "i18nfix config",
"i18n:check": "i18nfix check",
"i18n:fix": "i18nfix fix --in-place",
"i18n:fix:drop-extra": "i18nfix fix --in-place --drop-extra-keys",
"i18n:fix:translate": "i18nfix fix --in-place --translate",
"i18n:fix:translate:verbose": "i18nfix fix --in-place --translate -v"
}
}5) (Optional) Enable translation via .env
Create .env in your project root:
OPENAI_API_KEY=xxx
# or: OPENROUTER_API_KEY / ANTHROPIC_API_KEY / GEMINI_API_KEYThen add a translate section to i18nfix.config.json:
{
"translate": {
"provider": "openai",
"apiKeyEnv": "OPENAI_API_KEY",
"model": "gpt-4o-mini",
"batchSize": 50,
"concurrency": 3,
"delayMs": 0
}
}5) CI example (GitHub Actions)
Create .github/workflows/i18nfix.yml:
name: i18nfix
on:
pull_request:
push:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run i18n:checkQuick start (recommended workflow)
1) Create config (wizard)
npx i18nfix init
# or update later
npx i18nfix configThis writes i18nfix.config.json in the current directory.
2) Check
npx i18nfix check
# JSON report
npx i18nfix check --json3) Fix + Translate (recommended)
npx i18nfix fix --in-place --translate(If you only want structural fixes: npx i18nfix fix --in-place.)
Example included
Try the included example files:
npx i18nfix check --config examples/i18nfix.config.json
npx i18nfix fix --config examples/i18nfix.config.json --in-place --translateWhat the example demonstrates:
zh.jsonis missingapp.cta(will be added)home.subtitleis identical to base (flagged as possibly untranslated)- placeholder mismatch:
{name}vs{username} - printf mismatch:
%svs%d - extra key:
app.extraKey
Config file
Default filename: i18nfix.config.json
Minimal example:
{
"base": "locales/en.json",
"targets": ["locales/zh.json"],
"keyStyle": "auto",
"placeholderStyle": ["auto"],
"ignoreKeys": [],
"treatSameAsBaseAsUntranslated": true
}Translate (LLM providers)
Keys should be provided via environment variables (recommended). i18nfix will also auto-load a local .env file.
Defaults / behavior:
- Batch translation is enabled when
batchSizeis set (recommended for speed). If a batch output is missing keys or fails validation, i18nfix automatically retries those items in single-item mode. - By default i18nfix validates placeholders + HTML tags + basic Markdown markers.
- Translation cache is enabled by default (
.i18nfix-cache/translations.jsonl).
Example:
{
"translate": {
"provider": "openai",
"apiKeyEnv": "OPENAI_API_KEY",
"model": "gpt-4o-mini",
"batchSize": 50,
"concurrency": 3,
"retryCount": 3,
"retryBaseDelayMs": 400,
"cache": true,
"delayMs": 0
// maxItems is optional; when unset there is no limit
}
}Supported providers:
openai(env:OPENAI_API_KEY)openrouter(env:OPENROUTER_API_KEY) — OpenAI-compatible endpointclaude(env:ANTHROPIC_API_KEY)gemini(env:GEMINI_API_KEY)
Language handling:
targetLangis inferred from the target filename when not provided (e.g.zh.json,ja.json,fr-FR.json→zh,ja,fr).- from/to languages are printed by default during translation. Use
translate --no-show-langsto hide.
Documentation
- Website: https://zhanziyang.github.io/i18nfix/
- Recommended workflow: https://zhanziyang.github.io/i18nfix/docs/guides/workflow
Reference docs in-repo:
- CLI reference:
docs/CLI.md - Config reference:
docs/CONFIG.md
CLI notes
translate --mode:- default is
all(only keys with issues) missing/empty/untranslatedare narrower modes
- default is
maxItems:- optional (default: no limit)
- when set, i18nfix will translate at most that many strings per run and print how many remain.
- output validation (default on):
- placeholders must match
- HTML tags must be preserved
- basic Markdown markers must be preserved
- caching (default on):
.i18nfix-cache/translations.jsonl
License
MIT
