npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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

Readme

i18n-log

npm version License: MIT

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 --help

Quick Start

  1. Initialise the project configuration:

    npx i18log init

    The wizard looks for existing i18n config files (e.g. i18next.config.js, next-i18next.config.js) and common translation directories such as locales/ or src/locales/. Confirm a detected path or enter your own when prompted. A new i18log.config.ts file is created at the repo root.

  2. Run the audit:

    npx i18log lint

    You 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 (default i18n-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 help

Running 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 lint

Lint 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-warnings is 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 --quiet

Output 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.json

Compact

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 build

Generated 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