Complete i18n toolkit — runtime, studio, extract, sync, detect, translate.
Run and automate your entire internationalization workflow with one package.
Translify is a professional i18n runtime and framework-agnostic CLI that handles the complete translation lifecycle:
- Add missing keys to translation files across languages, preserving existing formatting
- Split large translation files into context files while still treating each language as one catalogue
- Detect unused, missing, duplicate, and cross-locale inconsistent translation entries, plus hardcoded user-facing text
- Translate automatically via AI providers (OpenAI or OpenRouter)
- Edit and translate visually in a local browser studio
- Audit your entire i18n health in one command
- Fix deterministic audit issues with
--dry-runpreviews - Render translations across Vanilla JavaScript, React, Next.js, Vue, Svelte, Angular, Solid, and server runtimes with ICU plurals, locale fallback, SSR-safe formatting, and typed catalogue keys
Built for teams that care about DX and translation quality.
Translify also exports a normalized, browser-safe world locale database with 250 country/territory entries and the complete current language registry:
import { getCountry, getLanguage } from '@ndnci/translify/locales';
getCountry('FR'); // names, codes, currencies, date/week formats, time zones, languages…
getLanguage('ce'); // Chechen (ISO aliases are supported)# Install globally
npm install -g @ndnci/translify
# Or run directly without installing
npx translify@latest initimport { createI18n } from '@ndnci/translify/vanilla';
import config from '../translify.config';
const i18n = createI18n(config);
i18n.t('home.welcome', { name: 'Ada' });React hooks and a provider are available from @ndnci/translify/react;
request-isolated Server Component and SSG helpers are available from
@ndnci/translify/next. Node.js and API routes can load the project config and
catalogues directly through @ndnci/translify/server.
translify initCreates a translify.config.ts in your project root.
translify auditRuns every check (missing, unused, duplicate values, duplicate keys, cross-locale inconsistencies, hardcoded text) in one pass — great for CI.
translify add-missing --dry-run
translify add-missingAdds missing keys to all language files, keeping them in sync with your base language, without touching the existing formatting of each file.
translify check-unusedFinds translation keys defined in your JSON files but never referenced in code.
translify split-translations --dry-run
translify split-translations --groups "tools=tool|foo,auth=auth"Splits files such as messages/en.json into context files such as
messages/en/tools.json, while audits and fixes continue to treat all files for
one language as a single catalogue.
Create a translify.config.ts at your project root:
import en from './messages/en.json';
import fr from './messages/fr.json';
// Optional editor autocomplete:
// /** @type {import('@ndnci/translify/config').TranslifyConfig} */
export default {
source: {
include: ['src/**/*.{ts,tsx,js,jsx}', 'app/**/*.{ts,tsx,js,jsx}'],
exclude: ['**/*.test.*', '**/node_modules/**'],
},
translations: {
default_language: 'en',
files: ['messages/**/*.json'],
split: {
depth: 1,
groups: [{ name: 'tools', match: ['tool'] }, 'auth'],
group_match: 'keys',
output_pattern: 'messages/{language}/{group}.json',
},
},
routing: {
locales: ['en', 'fr'],
locale_prefix: 'as-needed',
locale_detection: true,
pathnames: {
'/about': { en: '/about', fr: '/a-propos' },
},
},
runtime: {
locale: 'auto',
messages: { en, fr },
missing_message: 'key',
time_zone: 'Europe/Paris',
},
extraction: {
translation_functions: ['t', 'i18n.t', 'translate'],
namespace_functions: ['useTranslations', 'getTranslations'],
ignored_words: ['OK', 'API'],
ignored_patterns: ['^v[0-9]+$'],
},
ai_translation: {
enabled: false,
provider: 'openai',
openai_api_key: process.env.OPENAI_API_KEY,
openrouter_api_key: process.env.OPENROUTER_API_KEY,
model: 'gpt-5.6-luna',
temperature: 0,
batch_size: 50,
verify: false,
verify_model: undefined,
values_only: false,
},
};| Command | Description |
|---|---|
translify init |
Initialize a config file |
translify config-upgrade |
Add new config keys without overwriting existing values |
translify audit |
Full i18n audit (all checks combined) |
translify check-config |
Validate config values and unknown keys |
translify add-missing |
Add missing keys to translation files across languages |
translify add-languages |
Create files for one or more new languages |
translify split-translations |
Split large translation files by context |
translify audit-fix |
Fix deterministic audit issues |
translify hardcoded-fix |
Replace hardcoded text with i18n calls |
translify translate |
Auto-translate missing keys via AI |
translify studio |
Open the local browser translation studio |
translify check-missing |
Detect missing translation keys |
translify check-unused |
Detect unused translation keys |
translify check-duplicates |
Detect duplicate translation values and duplicate keys |
translify check-consistency |
Detect keys missing in some locales but present in others |
translify check-hardcoded |
Detect hardcoded user-facing text |
translify optimize |
Optimize and format translation files |
translify version |
Print the installed version and check for updates |
translify upgrade |
Update the globally installed CLI to the latest version |
-c, --config <path> Path to config file
--cwd <path> Working directory (default: process.cwd())
--dry-run Preview changes without writing files
--verbose Enable verbose output
-V, --version Print version
-h, --help Show help
| Framework / environment | Status |
|---|---|
| Vanilla JavaScript | ✅ Supported |
| React / Next.js | ✅ Supported |
| Vue / Nuxt | ✅ Supported |
| Svelte / SvelteKit | ✅ Supported |
| Angular | ✅ Supported |
| Solid / SolidStart | ✅ Supported |
| Vite | ✅ Supported |
| Astro | ✅ Supported |
| Node / serverless / SSR | ✅ Supported |
| Localized URL routing | ✅ Supported |
| Symfony | 🔜 Planned |
| Laravel / PHP | 🔜 Planned |
Translify integrates with OpenAI and OpenRouter to auto-translate your keys:
translify translate --locale frRequires ai_translation.enabled = true in your config and the provider API key
(OPENAI_API_KEY or OPENROUTER_API_KEY). We recommend
deepseek/deepseek-v4-flash through OpenRouter for the lowest-cost default, or
gpt-5.6-luna when calling OpenAI directly. Model prices change, so benchmark
both against a representative translation catalogue before standardizing.
See the model and real-cost guide for current links and measured Translify runs.
This repository is a monorepo. The following packages are published:
| Package | Description |
|---|---|
@ndnci/translify |
Runtime, framework adapters & CLI |
@ndnci/translify-core |
Core logic (scanner, parser, etc.) |
@ndnci/translify-config |
Config loading and validation |
@ndnci/translify-ai |
AI translation providers |
@ndnci/translify-shared |
Shared types and utilities |
The main package also exposes @ndnci/translify/locales for country and
language metadata, plus /vanilla, /react, /next, /vue, /svelte,
/angular, /solid, and /server runtime entry points, without loading them
into the CLI command bundle. Framework dependencies are optional peers: only the
adapter an application imports is required.
- Key extraction from TS/JS/TSX/JSX
- Translation file sync
- Unused / missing / duplicate detection
- AI translation via OpenAI and OpenRouter
- Full audit command
- Vanilla JavaScript, React, Next.js, Vue, Svelte, Angular, and Solid runtimes
- Vue SFC static extraction
- Angular template static extraction
- PHP/Laravel support
- Translation memory / TM integration
- Local translation studio
- VS Code extension
Contributions are welcome! See CONTRIBUTING.md for guidelines.
MIT License with Trademark Policy — see LICENSE and TRADEMARK_POLICY.md.
The name Translify and the @ndnci/translify npm scope are trademarks of
their respective owners and may not be used for redistributed or renamed
versions.