i18n-log
v1.0.0
Published
A powerful linter for internationalization (i18n) in JavaScript/TypeScript projects. Works like ESLint but specifically for translation issues - detecting untranslated text, missing keys, unused translations, and more.
Downloads
43
Maintainers
Readme
i18n-log
A powerful linter for internationalization (i18n) in JavaScript/TypeScript projects. Works like ESLint but specifically for translation issues - detecting untranslated text, missing keys, unused translations, and more with configurable severity levels and CI/CD integration.
🚀 Supports all major frameworks: React, Vue, Angular, Svelte, Next.js, Nuxt, and more!
Features
✅ Framework Support: React, Vue, Angular, Svelte, Next.js, Nuxt, and more
✅ Advanced Variable Tracking: Detects useTranslations('namespace') and similar patterns
✅ Linter-Style Output: Configurable rules, severity levels, and exit codes
✅ Multiple Output Formats: Stylish (default), JSON, compact for CI/CD integration
✅ Real-time Analysis: Fast AST-based parsing with comprehensive pattern detection
✅ CI/CD Ready: Proper exit codes, thresholds, and JSON reporting
Prerequisites
- Node.js 18+ (ships with npm and npx)
Install
# Install globally
npm install -g i18n-log
# Or as a dev dependency
npm install --save-dev i18n-log
# Or use with npx (no installation required)
npx i18n-log --helpQuick Start
Initialise the project configuration:
npx i18log initThe wizard looks for existing i18n config files (e.g.
i18next.config.js,next-i18next.config.js) and common translation directories such aslocales/orsrc/locales/. Confirm a detected path or enter your own when prompted. A newi18log.config.tsfile is created at the repo root.Run the audit:
npx i18log lintYou will see a colourised summary plus the number of missing translations, lone keys, and hard-coded snippets. A JSON report is written to the location configured in
i18log.config.ts(defaulti18n-report.json).
CLI Reference
Usage: i18log <command> [options]
Commands:
lint Run the translation audit (default)
init Create a config file with sensible defaults
help Show the CLI reference
lint options:
-c, --config <path> Use a specific config file
-o, --output <path> Override the JSON report output path
-f, --function <name> Override the translation function name (default: t)
-e, --extensions <list> Comma separated source extensions to scan
-t, --translations <list>
Comma separated translation file or directory paths
--ignore <list> Comma separated glob patterns to ignore
--no-prompt Skip interactive prompts when no config is found
--format <type> Output format: stylish (default), json, compact
--max-errors <n> Maximum errors before failing (CI/CD)
--max-warnings <n> Maximum warnings before failing (CI/CD)
--quiet Only report errors, ignore warnings
-h, --help Show help
init options:
-c, --config <path> Where to write the generated config (default: i18log.config.ts)
-y, --yes Accept detected suggestions without prompting
-h, --help Show helpRunning From Source
When working on the CLI itself you can still run:
npm start # ts-node src/cli.ts
npm run build # emit dist/ for the published package
node dist/cli.js lintLint Rules
i18n-log works as a linter with configurable rules and severity levels:
Available Rules
- missing-translation (error) –
t('key')usage without a matching translation entry - unused-translation (warning) – Translation keys defined in JSON but never used in code
- hardcoded-text (warning) – JSX text nodes or string literals that should be translated
- empty-translation (warning) – Translation keys with empty values
- duplicate-translation (info) – Different keys with identical translation values
- inconsistent-placeholders (error) – Missing or mismatched placeholders across languages
- missing-plural-forms (warning) – Keys that likely need plural forms
Exit Codes
- 0 – Success, no errors (warnings allowed unless
--max-warningsis set) - 1 – Linting errors found or threshold exceeded
Perfect for CI/CD pipelines:
# Fail on any error
npx i18log lint
# Fail if more than 10 warnings
npx i18log lint --max-warnings 10
# Only check for errors (ignore warnings)
npx i18log lint --quietOutput Formats
Stylish (default)
Colored, human-readable output similar to ESLint:
src/components/Header.jsx
12:8 error Translation key "header.title" is not defined (missing-translation)
24:10 warning Hardcoded text "Welcome" should be translated (hardcoded-text)
✖ 2 problems (1 error, 1 warning)JSON
Machine-readable format for tooling integration:
npx i18log lint --format json > results.jsonCompact
One issue per line for easy parsing:
npx i18log lint --format compact
# src/App.jsx:26:54: warning: Hardcoded text "English" [hardcoded-text]Configuration
Basic Config File
npx i18log init generates a typed config file:
// i18log.config.ts
import { defineConfig } from 'i18n-log';
export default defineConfig({
translationPaths: ['public/locales'],
sourceExtensions: ['.ts', '.tsx', '.js', '.jsx'],
translationFunctionName: 't',
outputPath: 'reports/i18n-report.json',
ignorePaths: ['**/node_modules/**', '**/dist/**']
});Lint Configuration
Customize rules in .i18nlintrc.json:
{
"rules": {
"missing-translation": "error",
"unused-translation": "warning",
"hardcoded-text": "warning",
"empty-translation": "warning",
"duplicate-translation": "info"
},
"ignoredKeys": [
"debug.*",
"internal.*"
],
"maxErrors": 0,
"maxWarnings": 50
}The CLI automatically discovers config files at the project root.
Supported Frameworks
i18n-log automatically detects and supports translation patterns from all major frameworks:
React Ecosystem
- Next.js intl:
useTranslations('namespace'),useMessages(),useLocale() - react-i18next:
useTranslation(),useTranslation('namespace'),<Trans> - react-intl/formatjs:
useIntl(),intl.formatMessage({ id: 'key' }) - Lingui:
useLingui(),_('key'),<Trans>
Vue Ecosystem
- vue-i18n Composition API:
useI18n(),t(),tc(),te(),d(),n() - Vue Options API:
this.$t(),this.$tc(),this.$te(),this.$d(),this.$n() - Nuxt i18n:
$t(),useI18n()
Angular Ecosystem
- ngx-translate:
TranslateService.get(),TranslateService.instant() - Angular Localize:
$localize\key`,$localize`:@@id:text``
Other Frameworks
- Svelte:
_('key'),$_('key'), svelte-i18n patterns - Framework Agnostic:
i18next.t(),polyglot.t(), generic patterns
Advanced Pattern Detection
i18n-log can detect complex patterns like:
// Namespace tracking
const t = useTranslations('dashboard.settings');
t('title') // → Detected as 'dashboard.settings.title'
// Multiple translation functions
const tNav = useTranslations('navigation');
const tForms = useTranslations('forms.validation');
// Destructuring
const { t, tc, te } = useI18n();
// Conditional assignments
const t = isAdmin ? useTranslations('admin') : useTranslations('user');
// Member expressions
i18n.t('key'), this.$t('key'), intl.formatMessage({ id: 'key' })Development
Type-check and build the distributable:
npm run lint
npm run buildGenerated artifacts are emitted to dist/.
Testing with Example App
The example/ folder contains a minimal React app for testing i18n-log:
# Build i18n-log first
npm run build
# Run the linter on the example app
cd example
npm install
npm run i18n:lint # Default stylish output
npm run i18n:lint:json # JSON format
npm run i18n:lint:quiet # Errors only
npm run i18n:check # Strict mode (fail on any warning)The example demonstrates:
- React components with i18next
- Multiple languages (EN, ES, FR)
- Various translation patterns (nested keys, interpolation)
- Common issues (unused keys, hardcoded text)
Local npm Alias
To experiment with the CLI without publishing, add an alias to your local package.json in the consuming project:
{
"devDependencies": {
"i18n-log": "file:../path-to/i18n-log"
}
}After running npm install, npx i18log will resolve to your local checkout so you can verify changes end-to-end.
Inspiration
The translation path discovery draws inspiration from the i18n Ally project.
License
MIT
