i18nkit

i18nkit

npmnodelicensezero-depsdocs


Universal i18n toolkit: extract translation keys, sync language files, detect missing translations. Zero dependencies, extensible via plugins.

Why i18nkit?

Managing translations is tedious: find hardcoded strings, create translation keys, keep language files in sync. i18nkit automates it.

ProblemSolution
Hardcoded strings in templatesAuto-extract translatable text
Manual pipe/function replacementAuto-apply in one command
Missing translations across langSync check with CI integration
Unused keys bloating bundlesOrphan detection to clean up
Manual translation copy-pasteAPI translation (free + pro)

Current Support

  • Angular + Transloco - Full support out of the box
  • PrimeNG components - Auto-extraction of translatable attributes

Extensible via plugins for other frameworks and libraries.

Quick Start

1. Install

npm install --save-dev @abdess76/i18nkit

2. Add scripts to package.json

{
  "scripts": {
    "i18n": "i18nkit --lang fr --merge",
    "i18n:apply": "i18nkit --auto-apply --init-langs en,fr",
    "i18n:check": "i18nkit --check-sync --strict",
    "i18n:orphans": "i18nkit --find-orphans --strict",
    "i18n:translate": "i18nkit --translate en:fr",
    "i18n:watch": "i18nkit --watch",
    "i18n:ci": "npm run i18n:check && npm run i18n:orphans"
  }
}

3. Run

# First time: extract + apply + create language files
npm run i18n:apply

# Development: watch mode
npm run i18n:watch

# Before commit / CI
npm run i18n:ci

How It Works

Before:

<h1>Welcome to our app</h1>
<button label="Submit" />
<input placeholder="Enter your name" />

After:

<h1>{{ 'home.titles.welcome_to_our_app' | transloco }}</h1>
<button [label]="'home.buttons.submit' | transloco" />
<input [placeholder]="'home.forms.enter_your_name' | transloco" />

Generated en.json:

{
  "home": {
    "titles": { "welcome_to_our_app": "Welcome to our app" },
    "buttons": { "submit": "Submit" },
    "forms": { "enter_your_name": "Enter your name" }
  }
}

Commands

Core Commands

CommandDescription
extractExtract i18n strings from source files
check-syncCompare language files for missing keys
find-orphansFind translation keys not used in source
translateTranslate a language file via API
watchWatch for file changes and re-run
backupManage backup sessions and restore files

NPM Scripts Examples

ScriptCommandDescription
npm run i18n--lang fr --mergeExtract, merge with existing
npm run i18n:apply--auto-apply --init-langsExtract + replace + create
npm run i18n:check--check-sync --strictValidate files are in sync
npm run i18n:orphans--find-orphans --strictFind unused keys
npm run i18n:translate--translate en:frTranslate via API
npm run i18n:watch--watchRe-run on file changes

Configuration

Create i18nkit.config.js in your project root:

module.exports = {
  src: 'src/app',
  i18nDir: 'src/assets/i18n',
  lang: 'fr',
  format: 'nested',
  backup: true,
  excludedFolders: ['node_modules', 'dist', '.git'],
};

Or i18nkit.config.json:

{
  "src": "src/app",
  "i18nDir": "src/assets/i18n",
  "lang": "fr",
  "format": "nested"
}

Supported Patterns

HTML Templates

PatternExample
Text content<h1>Welcome</h1>
Attributesalt, title, placeholder
Angular 17+@if, @for, @switch, @defer

Component Libraries

LibraryExtracted Attributes
PrimeNGlabel, tooltip, header
Angular Materialplaceholder, label
Bootstraptitle, alt

Translation APIs

# Free: MyMemory API
npm run i18n:translate

# Free with higher rate limit
npx i18nkit --translate fr:en --email you@example.com

# Pro: DeepL API (best quality)
DEEPL_API_KEY=xxx npx i18nkit --translate fr:en --deepl

CI/CD Integration

GitHub Actions

name: i18n
on: [push, pull_request]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci
      - run: npm run i18n:ci

Backup & Restore

Source files are backed up before modification. Full session management with restore, cleanup, and audit capabilities.

Automatic Backup

# Backup enabled by default with --auto-apply
npm run i18n:apply

# Disable backup if needed
npx i18nkit --auto-apply --no-backup

# Initialize backup structure explicitly
npx i18nkit --init-backups --auto-gitignore

Session Structure

.i18nkit/
├── .gitignore              # Auto-managed (excludes backups/, report.json)
├── report.json             # Current extraction report
└── backups/
    └── 2026-01-05_15-39-28_apply_ae9c/
        ├── manifest.json   # Session metadata with status tracking
        ├── report.json     # Archived extraction report
        └── src/            # Original source files

Session Management

# List all backup sessions
npx i18nkit --list-backups

# Show detailed info for a session
npx i18nkit --backup-info 2026-01-05_15-39-28_apply_ae9c

Restore from Backup

# Restore specific session
npx i18nkit --restore 2026-01-05_15-39-28_apply_ae9c

# Restore latest session
npx i18nkit --restore-latest

# Preview restore without applying
npx i18nkit --restore-latest --dry-run

Manual Cleanup

# Clean old sessions (interactive)
npx i18nkit --cleanup-backups

# Keep only last 5 sessions
npx i18nkit --cleanup-backups --keep 5

# Remove sessions older than 7 days
npx i18nkit --cleanup-backups --max-age 7

# Combine options
npx i18nkit --cleanup-backups --keep 3 --max-age 14

Auto-Cleanup Configuration

Old sessions are automatically cleaned up based on configuration.

// i18nkit.config.js
module.exports = {
  backup: {
    enabled: true,
    maxSessions: 10, // Keep max 10 sessions
    retentionDays: 30, // Delete sessions older than 30 days
    autoCleanup: true, // Auto-cleanup on each run
  },
};

Session Status

Sessions track their lifecycle status:

StatusDescription
pendingSession created, not started
backing_upBackup in progress
in_progressApply operation running
completedSuccessfully finished
failedError occurred (check manifest)
restoredFiles restored from this session

Key Mapping

Override auto-generated keys with .i18n-keys.json:

{
  "Welcome to our app": "common.welcome",
  "Submit": "buttons.submit",
  "Cancel": "buttons.cancel"
}

Plugin System

i18nkit is built to be extended. Create plugins for any framework, library, or translation service.

Plugin TypePurposeExample Use Case
parserExtract strings from filesVue, Svelte, React
adapterTransform to i18n syntaxi18next, vue-i18n
providerTranslate via APIGoogle, AWS, Azure

Quick Example

// plugins/my-parser.js
module.exports = {
  name: 'parser-vue',
  type: 'parser',
  meta: { description: 'Extract from Vue SFC' },
  extensions: ['.vue'],
  detect: ctx => ctx.pkg.dependencies?.['vue'],
  extract(content) {
    return [{ text: 'Hello', context: 'greeting' }];
  },
};
// i18nkit.config.js
module.exports = {
  plugins: ['./plugins/my-parser.js'],
};

Full guide: PLUGINS.md

Community Plugins

Publish your plugin to npm:

npm publish i18nkit-parser-svelte

i18nkit auto-discovers packages named i18nkit-* or @yourorg/i18nkit-*.

Want to contribute? Check builtin plugins for reference implementations.

Options

Global Options

--config <path>       Path to config file (default: i18nkit.config.js)
--src <path>          Source directory (default: src/app)
--locales <path>      Locales directory (default: src/assets/i18n)
--default-lang <code> Default language (default: fr)
--dry-run             Preview changes without writing
--verbose             Detailed output
--help, -h            Show help
--version, -v         Show version

Extraction Options

--lang <code>         Language code for output file
--format <type>       Output format: nested | flat (default: nested)
--merge               Merge with existing translations
--auto-apply          Extract AND apply pipes in one command
--init-langs <codes>  Create language files (e.g., en,fr,es)
--include-translated  Include already translated strings
--extract-ts-objects  Extract from TypeScript object literals
--skip-translated     Skip already translated strings (default: true)

Validation Options

--check-sync          Compare language files for missing keys
--find-orphans        Find unused translation keys
--strict              Exit with error code 1 on issues
--ci                  CI mode (strict + json output)

Translation Options

--translate <src:tgt> Translate via API (e.g., fr:en)
--deepl               Use DeepL API (requires DEEPL_API_KEY)
--mymemory            Use MyMemory API (default)
--email <email>       Email for MyMemory rate limits

Backup Options

--backup              Enable backup before modifications (default)
--no-backup           Disable backup
--list-backups        List all backup sessions
--backup-info <id>    Show backup session details
--restore [id]        Restore from backup (latest if no id)
--restore-latest      Restore from most recent backup
--cleanup-backups     Remove old backup sessions
--keep <n>            Keep last n sessions (default: 10)
--max-age <days>      Max session age in days (default: 30)
--init-backups        Initialize backup directory structure
--auto-gitignore      Auto-add .i18nkit to .gitignore

Watch Options

--watch               Watch mode for file changes

Exit Codes

CodeMeaning
0Success
1Missing translations or sync problems (--strict)
2Error (file not found, parse error)

API Documentation

Full API reference: abdess.github.io/i18nkit

Requirements

  • Node.js >= 22.0.0

Contributing

i18nkit welcomes community contributions:

  • Plugins - Create parsers for new frameworks, adapters for i18n libraries, or providers for translation APIs
  • Bug reports - Open an issue with reproduction steps
  • Feature requests - Suggest improvements via GitHub issues

See PLUGINS.md for the plugin development guide.

License

MIT


GitHub · npm · Issues · Plugin Guide