react-i18n-audit
v0.1.2
Published
I18n audit for React/Next: fix, report, check
Maintainers
Readme
react-i18n-audit
A CLI to audit i18n keys in React/Next.js projects. It finds missing keys, unused keys, and extra keys across your locales, can generate an HTML report, and can automatically fix issues.
- report: generate an HTML report
- check: run a check that fails (non‑zero exit code) if there are issues — perfect for CI
- fix: remove unused/extra keys and add placeholders for missing ones
Supported patterns out of the box: t('key'), i18n.t('key'), useTranslations('NS')('key'), intl.formatMessage({ id: 'key' }), and factories like createTranslator({ namespace: 'NS', ... }) / getStaticTranslator({ namespace: 'NS', ... }). You can customize hook, function, and factory names.
Installation
npm i -D react-i18n-audit
# or
yarn add -D react-i18n-audit
# or
pnpm add -D react-i18n-auditRun via npx:
npx react-i18n-audit --helpNode 18+ is required.
Quick start
Create i18n-audit.config.json in the project root:
{
"sourceGlobs": ["src/**/*.{ts,tsx,js,jsx}"],
"localeFileGlobs": [
"public/locales/{locale}.json",
"public/locales/{locale}/**/*.json"
],
"placeholderText": "[MISSING]",
"translationHookNames": ["useTranslations", "useFmtTranslations"],
"translationFunctionNames": ["t"],
"translationFactoryNames": ["createTranslator", "getStaticTranslator"],
"excludeKeyPatterns": ["\\.polyglot-description$"]
}- sourceGlobs: where to scan code for used translation keys
- localeFileGlobs: where to load locale JSON files; use
{locale}as a placeholder for the language - placeholderText: text to insert for missing keys when running
fix - translationHookNames: hook names that return a namespaced translator (e.g.
useTranslations('NS')) - translationFunctionNames: translation function names (e.g.
t,tMeta) - excludeKeyPatterns: array of RegExp strings; matching keys are excluded from analysis
Commands
report
Generate an HTML report of i18n issues.
react-i18n-audit report [options]Options:
-c, --config <path>: path to JSON config (by default the tool looks fori18n-audit.config.json)--out <path>: path to output HTML file (default:i18n-audit-report.html)
Example:
react-i18n-audit report --config i18n-audit.config.json --out artifacts/i18n-report.htmlPrints the path to the HTML and a summary (missing, unused, extra). If issues are found, sets process.exitCode = 1 (handy for CI while still producing artifacts).
check
Scan the project and fail when issues are found.
react-i18n-audit check [options]Options:
-c, --config <path>: path to JSON config--silent: suppress console output; exit code behavior is unchanged
Examples:
react-i18n-audit check --config i18n-audit.config.json
react-i18n-audit check --silentExit codes: 0 — ok, 1 — problems found (missing, unused, or extra keys).
fix
Automatically modify locale files in place: remove unused/extra keys and add placeholders for missing ones.
react-i18n-audit fix [options]Options:
-c, --config <path>: path to JSON config--remove-only: only remove unused/extra keys, do not add missing ones
Behavior:
- For adding missing keys,
excludeKeyPatternsare respected (matching keys are not created) - For deletions (unused/extra),
excludeKeyPatternsare ignored — cleanup happens regardless - For each locale, all JSON files matching
localeFileGlobsare updated in place - Missing keys are added to a "target" file for the locale — preferably a
.../common.json, otherwise the first matched file; if none exist, a reasonable path is created based on the first glob
Examples:
react-i18n-audit fix
react-i18n-audit fix --remove-only
react-i18n-audit fix -c i18n-audit.config.jsonHow it works
- The scanner walks
sourceGlobsand extracts used keys via AST (@babel/parser + traverse) with a regex fallback. - Locales are loaded from all files found by
localeFileGlobs. Objects are flattened to dot-notation keys. - The report is built:
- missing: key is used in code but absent in a specific locale
- unused: key exists in a locale but is not used in code (locale-specific)
- extra: key exists in at least one locale but is not used anywhere
reportrenders HTML (defaulti18n-audit-report.html).checkprints a summary and sets the exit code.fixdeletes unused/extra keys and adds placeholders for missing ones.
Configuration
File: i18n-audit.config.json (JSON). You can pass a custom path via --config.
Defaults:
{
"sourceGlobs": ["src/**/*.{ts,tsx,js,jsx}"],
"localeFileGlobs": [],
"placeholderText": "[MISSING]",
"translationHookNames": ["useTranslations", "useFmtTranslations"],
"translationFunctionNames": ["t"],
"translationFactoryNames": ["createTranslator", "getStaticTranslator"],
"excludeKeyPatterns": ["\\.polyglot-description$"]
}Notes:
localeFileGlobsis required. If omitted, the tool throws with a helpful example.- RegExp values must be strings in JSON (escape backslashes accordingly).
Example localeFileGlobs:
[
"public/locales/{locale}.json",
"public/locales/{locale}/**/*.json",
"apps/web/public/i18n/{locale}/**/*.json"
]CI integration
checkreturns1if issues are found. Useful as a quality gate.reportalso sets exit code1when issues exist and produces an HTML artifact for easy inspection.
GitHub Actions example (snippet):
- name: Audit i18n
run: |
npm ci
npx react-i18n-audit report --out i18n-report.html || true
npx react-i18n-audit check
continue-on-error: falseSupported code patterns
- i18next:
t('key'),i18n.t('key') - next-intl:
useTranslations('NS')('key')andconst t = useTranslations('NS'); t('key') - FormatJS:
intl.formatMessage({ id: 'key' })
You can extend/override these via translationHookNames, translationFunctionNames, and translationFactoryNames in the config.
Limitations and notes
- The parser runs with
typescript+jsx. If parsing fails for a file, a simplified regex fallback is used. excludeKeyPatternsare applied when loading locales (keys are filtered immediately). For deletions infix, locales are reloaded without exclusions to ensure full cleanup.- Keys are treated as flat (
a.b.c). Nested JSON objects are automatically flattened/unflattened when reading/writing.
License
MIT
