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

@yaos-git/i18n-kit

v226.0.1

Published

Universal i18n linting CLI and TUI workspace editor

Downloads

74

Readme

Node Version TypeScript Version React Version

Uses Ink Uses Vitest Uses Biome


Table of Contents

Getting Started

Features

Development


Overview

i18n-kit treats internationalization as a data-integrity problem. Instead of just checking "key exists", it parses ICU MessageFormat strings from your base locale, extracts grammatical contracts (variables, plural branches, string length), and validates every translation against those contracts.

What Makes This Project Unique

  • Contract-Based Validation: Extracts variables, plural branches, and length buckets from the base locale — translations must satisfy the same grammatical contract
  • CLDR-Aware Plural Checking: Uses Intl.PluralRules to validate that Arabic has all 6 categories, not just one/other
  • Expansion Guard: Detects translations that are too long for their UI context based on configurable thresholds per length bucket
  • Dual Binary: Lean CLI for CI/CD pipelines + full React/Ink TUI for interactive editing

Installation

# Install globally from npm
npm install -g @yaos-git/i18n-kit

# Or install as a dev dependency
npm install -D @yaos-git/i18n-kit

From Source

# Clone the repository
git clone https://github.com/YAOSGit/i18n-kit.git
cd i18n-kit

# Install dependencies
npm install

# Build the project
npm run build

# Link globally (optional)
npm link

Quick Start

# Initialize a config file
i18n-kit init

# Lint your locale files
i18n-kit check

# View per-locale health scores
i18n-kit health

# Generate a pseudo-locale file
i18n-kit pseudo

CLI Usage

i18n-kit check [--config <path>] [--fix]   Lint locale files against grammatical contracts
i18n-kit health [--config <path>]           Show per-locale health scores
i18n-kit pseudo [--config <path>] [-o <path>]   Generate pseudo-localized locale file
i18n-kit init                               Scaffold an i18n-kit.config.ts file
i18n-kit --help, -h                         Show help message
i18n-kit --version, -v                      Show version information

Exit Codes

| Code | Meaning | |------|---------| | 0 | No errors found | | 1 | Errors found in locale files | | 2 | Config loading failed |

Examples

# Check with default config (i18n-kit.config.ts)
i18n-kit check

# Check with custom config path
i18n-kit check --config ./config/i18n.config.ts

# Auto-fix ghost keys
i18n-kit check --fix

# Output health as bar chart
i18n-kit health

# Generate pseudo-locale to custom path
i18n-kit pseudo -o ./locales/pseudo.json

6 Built-in Rules

| Rule | Default | Description | |------|---------|-------------| | variable-parity | error | Ensures all {variables} from the base locale appear in translations | | icu-syntax | error | Validates ICU MessageFormat syntax is parseable | | plural-completeness | error | Checks all CLDR-required plural categories are present per locale | | expansion-guard | warning | Detects translations that exceed length thresholds for their bucket | | ghost-keys | warning | Finds keys in translations that don't exist in the base locale | | missing-keys | info | Reports base locale keys missing from translations |

Three-Tier Severity Cascade

Severity is resolved with three tiers of precedence:

  1. Per-key overrideoverrides['key'].severity['rule']
  2. Global rule configrules['rule']
  3. Rule default — hardcoded in the rule definition
export default defineConfig({
  baseLocale: 'en',
  locales: './locales/*.json',
  rules: {
    'ghost-keys': 'error',        // Global: promote to error
  },
  overrides: {
    'legacy.key': {
      severity: { 'ghost-keys': 'off' },  // Per-key: suppress
    },
  },
});

Grammatical Contracts

For each key in the base locale, i18n-kit extracts a grammatical contract:

  • Variables: {name}, {count} — the ICU arguments the message expects
  • Plural Branches: one, other, few, many — the categories the message defines
  • Length Bucket: short (≤10 chars), medium (≤40), long (>40) — for expansion thresholds

Translations are validated against these contracts, not just checked for existence.


Pseudo-Localization

The pseudo command generates a pseudo-locale file that transforms all base strings using a Normalize → Transliterate → Replace pipeline:

English:  "Welcome, {name}!"    → "[~ ₩3|(0₥3, {name}! ~]"
French:   "Bienvenue, {name}!"  → "[~ 813ñ√3ñµ3, {name}! ~]"
Japanese: "ようこそ"              → "【~ @8( ~】"
  • ICU variables and plural/select structures are never transformed
  • Script-aware wrappers: [~ ~] for Latin, «~ ~» for RTL, 【~ ~】 for CJK

Health Scoring

Per-locale health scores are computed from weighted diagnostics:

| Severity | Penalty | |----------|---------| | error | 5 points | | warning | 2 points | | info | 0.5 points |

Score = max(0, 100 - total penalty)

i18n-kit health

# Output:
#   de       ████████████████████████████░░ 95.0%
#   pt       ████████████████████░░░░░░░░░░ 83.5%
#   ar       ██████████████░░░░░░░░░░░░░░░░ 62.0%

TypeScript Config

i18n-kit uses a TypeScript config file with a defineConfig helper for type-safe configuration:

import { defineConfig } from '@yaos-git/i18n-kit';

export default defineConfig({
  baseLocale: 'en',
  locales: './locales/*.json',

  rules: {
    'variable-parity': 'error',
    'expansion-guard': 'warning',
    'ghost-keys': 'off',
  },

  expansion: {
    short: { maxChars: 10, threshold: 1.0 },
    medium: { maxChars: 40, threshold: 0.4 },
    long: { threshold: 0.15 },
  },

  overrides: {
    'marketing.hero': { expansion: 'ignore' },
  },
});

Also supports JSON and YAML config files (i18n-kit.config.json, i18n-kit.config.yaml).


Available Scripts

Development Scripts

| Script | Description | |--------|-------------| | npm run dev | Run TypeScript checking + test watcher concurrently | | npm run dev:typescript | Run TypeScript type checking in watch mode | | npm run dev:test | Run Vitest in watch mode |

Build Scripts

| Script | Description | |--------|-------------| | npm run build | Bundle CLI and TUI with esbuild |

Lint Scripts

| Script | Description | |--------|-------------| | npm run lint | Run type checking, linting, formatting, and audit | | npm run lint:check | Check code for linting issues with Biome | | npm run lint:fix | Check and fix linting issues with Biome | | npm run lint:format | Format all files with Biome | | npm run lint:types | Run TypeScript type checking only | | npm run lint:audit | Run npm audit |

Testing Scripts

| Script | Description | |--------|-------------| | npm test | Run all tests (unit, react, types, e2e) | | npm run test:unit | Run unit tests | | npm run test:react | Run React component tests | | npm run test:types | Run type-level tests | | npm run test:e2e | Build and run end-to-end tests |


Tech Stack

Core

Build & Development

UI


Project Structure

i18n-kit/
├── src/
│   ├── app/                        # Application entry points
│   │   ├── cli.ts                  # CLI entry point (Commander)
│   │   ├── tui.tsx                 # TUI entry point (Ink)
│   │   ├── app.tsx                 # Main TUI layout
│   │   ├── theme.ts                # TUI theme
│   │   └── commands.ts             # TUI command definitions
│   ├── commands/                   # CLI commands
│   │   ├── check.ts                # i18n-kit check
│   │   ├── health.ts               # i18n-kit health
│   │   ├── pseudo.ts               # i18n-kit pseudo
│   │   └── init.ts                 # i18n-kit init
│   ├── core/                       # Business logic (shared CLI + TUI)
│   │   ├── ConfigLoader/           # TypeScript config loading via jiti
│   │   ├── FileDiscovery/          # Glob-based locale file resolution
│   │   ├── Parser/                 # JSON → ICU AST parsing + flatten
│   │   ├── ContractExtractor/      # Base locale → grammatical contracts
│   │   ├── RuleEngine/             # Rule registry + severity cascade
│   │   │   └── rules/              # 6 built-in rules
│   │   ├── Validator/              # Pipeline orchestrator
│   │   ├── Reporter/               # Terminal + JSON output
│   │   ├── HealthScorer/           # Weighted diagnostic scoring
│   │   └── PseudoLocalizer/        # Script-aware pseudo-localization
│   ├── types/                      # Core type definitions
│   │   ├── Severity/               # Severity + DiagnosticSeverity
│   │   ├── Config/                 # I18nKitConfig + ResolvedConfig
│   │   ├── Workspace/              # Workspace + LocaleData + LocaleEntry
│   │   ├── Contract/               # GrammaticalContract + PluralBranch
│   │   ├── Diagnostic/             # Diagnostic + AutoFix
│   │   └── Rule/                   # Rule + RuleContext
│   ├── components/                 # TUI React components
│   │   ├── StatusBar/              # Header bar with diagnostics summary
│   │   ├── KeyTree/                # Filterable key list
│   │   ├── FilterPanel/            # Diagnostic filter selector
│   │   ├── KeyDetail/              # Per-key translation cards
│   │   ├── TranslationCard/        # Single locale translation display
│   │   ├── IcuEditor/              # ICU structure viewer
│   │   ├── FakerLab/               # Variable faker preview
│   │   ├── PseudoPreview/          # Pseudo-localization preview
│   │   └── HealthDashboard/        # Per-locale health bar chart
│   ├── providers/                  # React context providers
│   │   ├── WorkspaceProvider/      # Validation state
│   │   ├── NavigationProvider/     # Key selection + tab state
│   │   ├── EditorProvider/         # Dirty entry tracking
│   │   └── FakerProvider/          # Variable generation
│   └── hooks/                      # Re-exported provider hooks
├── e2e/                            # End-to-end CLI tests
│   ├── fixtures/                   # Test locale fixtures
│   └── *.e2e.ts                    # CLI command tests
├── examples/                       # Usage examples
│   ├── basic/                      # Minimal setup
│   ├── custom/                     # Custom rules and overrides
│   └── integration/                # CI/CD integration
└── dist/                           # Built output
    ├── cli.js                      # Headless CLI binary
    └── tui.js                      # React/Ink TUI binary