Git-native translation management with intelligent stale detection. Hash-based state tracking ensures your translations stay synchronized with your code.
npm install i18n-state-manager> Git-native translation management with intelligent stale detection


Most translation management tools can detect missing translations, but they cannot identify when translations become outdated.
When you change source text from "Click to save" to "Click to save changes", other languages still reference the old translation. Traditional tools don't catch this because the translation technically exists.
i18n-state-manager uses hash-based state tracking to detect three translation states:
- Up-to-date - Translation matches current source text
- Missing - Translation doesn't exist
- Stale - Translation exists but source text changed
- Node.js >= 16.0.0
- ripgrep (required for check-usage and find-unused commands)
Install ripgrep:
``bashmacOS
brew install ripgrep
Quick Start
`bash
Install
npm install -D i18n-state-managerInitialize
npx i18n-state initSync translations
npx i18n-state syncCheck status
npx i18n-state verify
`Features
$3
- Hash-based stale detection - Track when translations become outdated
- Git-trackable state - State files commit alongside your code
- Zero cloud dependencies - Everything runs locally
- CI/CD enforcement - Prevent untranslated strings from being deployed
- Template generation - Create translation files with TODO/STALE markers
$3
- 7 commands - Complete workflow coverage
- Static code analysis - Finds translation keys in your code
- Unused key detection - Clean up legacy translations
- Duplicate detection - Catch copy-paste errors
- TypeScript support - First-class TypeScript integration
How It Works
$3
Contains SHA1 hashes of all source language strings:
`json
{
"common.save": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3",
"common.cancel": "c3499c2729730a7f807efb8676a92dcb6f8a3f8f"
}
`$3
Tracks translation status for each locale:
`json
{
"fr": {
"common.save": {
"source": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3",
"translation": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8"
}
}
}
`$3
When English changes from "Save" to "Save changes":
- Manifest hash updates
- State hash doesn't match
- System marks translation as stale
Commands
$3
Update manifest and state files after changing translations.$3
Check for missing and stale translations (fails on issues - perfect for CI).`bash
$ npx i18n-state verifyTranslation Statistics:
fr: 1465/1540 (95%) up-to-date, 0 stale
de: 1487/1540 (97%) up-to-date, 0 stale
Missing translations:
[fr] 75 missing keys:
- settings.newFeature.title
- settings.newFeature.description
...
`$3
Show translation coverage summary (non-failing).$3
Find translation keys used in code and verify they exist in source locale.`bash
$ npx i18n-state check-usageFound 1172 unique translation keys in source code
Keys used in code but missing from en.ts:
- modals.newModal.title
`$3
Find keys in source locale that aren't used in source code.$3
Check for duplicate keys in translation files.$3
Generate a translation template file.`bash
$ npx i18n-state generate-template frStatistics:
Total keys: 1540
Up-to-date: 1465
Missing: 75
Stale: 0
Template file contains:
- Existing translations (preserved)
- Missing keys marked "TODO: English text"
- Stale keys marked "STALE: old translation"
`Configuration
Create
i18n-state.config.json:`json
{
"sourceLocale": "en",
"resourcesDir": "src/i18n/resources",
"manifestPath": "i18n.manifest.json",
"statePath": "i18n.state.json",
"scanDirs": ["src"],
"scanExtensions": ["ts", "tsx", "js", "jsx"],
"patterns":
{
"name": "t()",
"regex": "\\bt\\([\"'[\"']\\)"
},
{
"name": "translate()",
"regex": "\\btranslate\\(\"'[\"']\\)"
}
]
}
`Typical Workflow
$3
`bash
1. Add English strings
Edit src/i18n/resources/en.ts
2. Update manifest/state
npx i18n-state sync3. Generate templates for other locales
npx i18n-state generate-template fr
npx i18n-state generate-template de4. Translate TODO items in *.template.ts files
5. Verify everything
npx i18n-state verify
`$3
Add to your GitHub Actions workflow:
`yaml
- name: Check translations are up-to-date
run: |
npm run i18n-state sync
if [[ -n "$(git status --porcelain)" ]]; then
echo "Translation files are out of date"
exit 1
fi
npm run i18n-state verify
`Translation File Format
Currently supports TypeScript (.ts) files only:
`typescript
import { Translation } from "../types";export const fr: Translation = {
common: {
save: "Enregistrer",
cancel: "Annuler",
},
settings: {
title: "Paramètres",
}
};
``Note: JSON and JavaScript formats are not currently supported. Translation files must be TypeScript files with the structure shown above.
| Feature | i18n-state-manager | i18n-tasks | Locize | react-intl |
|---------|-------------------|------------|---------|------------|
| Stale detection | Hash-based | No | Timestamp-based | No |
| Local-first | Yes | Yes | Cloud-only | Yes |
| Find unused keys | Yes | Yes | Yes | Basic |
| CI/CD enforcement | Yes | Manual | Yes | No |
| Template generation | Yes | No | Web UI | No |
| Cost | Free | Free | $500+/mo | Free |
Contributions welcome! Please read our Contributing Guide.
MIT © Callum Alpass
Developed as part of TaskNotes, an Obsidian plugin for task management.