i18n-state-manager
v0.1.0
Published
Git-native translation management with intelligent stale detection. Hash-based state tracking ensures your translations stay synchronized with your code.
Maintainers
Readme
i18n-state-manager
Git-native translation management with intelligent stale detection
The Problem
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.
The Solution
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
Requirements
- Node.js >= 16.0.0
- ripgrep (required for
check-usageandfind-unusedcommands)
Install ripgrep:
# macOS
brew install ripgrep
# Ubuntu/Debian
apt install ripgrep
# Arch Linux
pacman -S ripgrep
# Fedora
dnf install ripgrep
# Windows
choco install ripgrepQuick Start
# Install
npm install -D i18n-state-manager
# Initialize
npx i18n-state init
# Sync translations
npx i18n-state sync
# Check status
npx i18n-state verifyFeatures
Core Features
- 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
Developer Experience
- 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
1. Manifest File (i18n.manifest.json)
Contains SHA1 hashes of all source language strings:
{
"common.save": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3",
"common.cancel": "c3499c2729730a7f807efb8676a92dcb6f8a3f8f"
}2. State File (i18n.state.json)
Tracks translation status for each locale:
{
"fr": {
"common.save": {
"source": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3",
"translation": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8"
}
}
}3. Intelligent Detection
When English changes from "Save" to "Save changes":
- Manifest hash updates
- State hash doesn't match
- System marks translation as stale
Commands
i18n-state sync
Update manifest and state files after changing translations.
i18n-state verify
Check for missing and stale translations (fails on issues - perfect for CI).
$ npx i18n-state verify
Translation 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
...i18n-state status
Show translation coverage summary (non-failing).
i18n-state check-usage
Find translation keys used in code and verify they exist in source locale.
$ npx i18n-state check-usage
Found 1172 unique translation keys in source code
Keys used in code but missing from en.ts:
- modals.newModal.titlei18n-state find-unused
Find keys in source locale that aren't used in source code.
i18n-state check-duplicates
Check for duplicate keys in translation files.
i18n-state generate-template <locale>
Generate a translation template file.
$ npx i18n-state generate-template fr
Statistics:
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:
{
"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
Adding New Features
# 1. Add English strings
# Edit src/i18n/resources/en.ts
# 2. Update manifest/state
npx i18n-state sync
# 3. Generate templates for other locales
npx i18n-state generate-template fr
npx i18n-state generate-template de
# 4. Translate TODO items in *.template.ts files
# 5. Verify everything
npx i18n-state verifyCI/CD Integration
Add to your GitHub Actions workflow:
- 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 verifyTranslation File Format
Currently supports TypeScript (.ts) files only:
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.
Comparison
| 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 |
Contributing
Contributions welcome! Please read our Contributing Guide.
License
MIT © Callum Alpass
Acknowledgments
Developed as part of TaskNotes, an Obsidian plugin for task management.
