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

v3.3.2

Published

Research-grade translation engine for i18n projects. Pluggable methods, per-pair quality tiers, and deterministic script converters. Supports JSON (next-intl, i18next), TOML, and YAML (Hugo).

Readme

i18n-rosetta

npm version CI License: MIT

🌐 README translationstranslated by rosetta, of course: Français · Deutsch · Español · Português · Nederlands · 日本語 · 한국어 · 简体中文 · ไทย · Tiếng Việt · Filipino · العربية

Translate your locale files with one command:

npx i18n-rosetta sync

Rosetta auto-detects your locale files, their format, and the target languages. It translates missing keys, skips what's already done, and writes the results. That's it.

Why Not Just Script It Yourself?

You could write a quick script that loops through your English keys and calls Google Translate. Most developers do — it takes about 30 lines. Here's why it breaks:

  • No change detection. When you update an English string, the translation stays stale forever. Rosetta tracks every source value with SHA-256 hashes and re-translates only what changed.
  • No batching. One API call per key means 200 keys = 200 round trips. Rosetta batches intelligently (configurable, default 30 keys/batch for LLM, 128 for Google).
  • No quality gate. Machine translation hallucinates, echoes the source back, or outputs in the wrong script. Rosetta validates every translation before writing it — wrong-script, length inflation, and source echoes are caught and rejected.
  • No format awareness. Hardcoded to JSON? Rosetta handles JSON, TOML, YAML, and Hugo Markdown (frontmatter + body) with auto-detection.
  • No safety. Rosetta guards against prototype pollution, path traversal via crafted locale codes, and code block corruption during Markdown translation.

Rosetta is the production version of that script.

Quick Start

npm install --save-dev i18n-rosetta

Get an API Key

Rosetta needs a translation backend. Pick one:

| Provider | Key | Best for | |----------|-----|----------| | OpenRouter (recommended) | OPENROUTER_API_KEY | Content-heavy projects, Markdown, 200+ models | | OpenAI | OPENAI_API_KEY | Direct GPT-4o access | | Anthropic | ANTHROPIC_API_KEY | Direct Claude access | | Gemini | GEMINI_API_KEY | Free tier available | | DeepL | DEEPL_API_KEY | European languages, glossary support | | Google Translate | GOOGLE_TRANSLATE_API_KEY | 130+ languages, high volume |

Fastest start (free): Sign up at aistudio.google.com for a free Gemini key:

export GEMINI_API_KEY=AI...
npx i18n-rosetta sync --method gemini

OpenRouter (200+ models): Sign up at openrouter.ai, then:

export OPENROUTER_API_KEY=sk-or-v1-...
npx i18n-rosetta sync

Google Translate alternative (key-value pairs only — no Markdown awareness):

export GOOGLE_TRANSLATE_API_KEY=...
npx i18n-rosetta sync --method google-translate

Note: If only GOOGLE_TRANSLATE_API_KEY is set, rosetta auto-switches to Google Translate. No config change needed. Uses the REST API directly — no SDK, no service account, no pip install. Just the key.

That's it. For more control, create a config file:

npx i18n-rosetta init                        # guided wizard — walks you through registers, methods, and content
npx i18n-rosetta init --yes --langs fr,de,ja  # quick setup with specific languages and default registers

Each language comes with register presets — pre-built tone/formality instructions tuned to its linguistic system (vouvoiement for French, Siezen for German, です/ます for Japanese, 해요체 for Korean). The init wizard lets you browse and pick presets, or pass --yes to accept the defaults.

Non-English Source

If your source language isn't English:

i18n-rosetta sync --source fr                      # CLI flag

Or set it permanently in your config:

{ "inputLocale": "fr" }

What It Does

You handle the i18n framework (next-intl, i18next, Hugo). Rosetta handles the translation files.

  • Multi-format — JSON, TOML, YAML, Hugo Markdown (front matter + body), and XLIFF 1.2
  • Incremental — Only translates what changed (SHA-256 hash tracking)
  • Cached — Translation Memory stores previous results; re-running sync costs nothing for unchanged keys
  • Quality-gated — Validates every translation: catches hallucinations, wrong-script output, source echoes, and length inflation
  • Content-aware — LLM methods shield code blocks, shortcodes, links, and interpolation variables during Markdown translation
  • Pipeline toolslint, audit, integrity, seo for CI gates
  • XLIFF interop — Export translations for professional review in CAT tools (memoQ, SDL Trados, Phrase), import them back
  • Zero dependencies — Node.js built-ins only. No SDKs, no native modules. Requires Node 20+

Beyond Google Translate

The quick start gets you running with an LLM or Google Translate. But Google Translate supports ~130 languages. There are over 7,000.

Rosetta's core idea: the translation method is configurable per language pair. Use Google Translate for French, an LLM with morphological coaching for Plains Cree, and a community-hosted API for Quechua — all in the same project, all with the same CLI.

{
  "version": 3,
  "pairs": {
    "en:fr": { "method": "google-translate" },
    "en:ja": { "method": "llm" },
    "en:crk": { "methodPlugin": "crk-coached-v1" }
  }
}

If you can figure out how to translate a language pair — through prompt engineering, community dictionaries, FST pipelines, or fine-tuned models — rosetta lets you package that method as a plugin and deploy it alongside everything else.

Born from translating a production website into Plains Cree, where no off-the-shelf API exists. The per-pair architecture isn't theoretical — it exists because one project needed Google Translate for French and a coached FST pipeline for an Indigenous language, running side by side in the same sync command.

The companion MT Eval Harness lets you benchmark and compare translation approaches, then export working methods as rosetta plugins. Anyone who speaks both languages can develop, test, and share a translation method — no proprietary platform required.

Choose Your Method

Rosetta supports 10 translation methods. Each language pair can use a different method.

LLM providers — best for quality, Markdown-aware, coaching-compatible:

| Method | Key | What It Does | |--------|-----|-------------| | llm (default) | OPENROUTER_API_KEY | LLM via OpenRouter — 200+ models, auto-routing | | llm-coached | OPENROUTER_API_KEY | LLM + grammar rules, dictionaries, style notes | | openai | OPENAI_API_KEY | Direct OpenAI API (gpt-4o, gpt-4o-mini) | | anthropic | ANTHROPIC_API_KEY | Direct Anthropic API (Claude Sonnet, Haiku, Opus) | | gemini | GEMINI_API_KEY | Direct Google Gemini API (Flash, Pro) — free tier available |

Traditional MT — best for speed, cost, and high-volume key-value pairs:

| Method | Key | What It Does | |--------|-----|-------------| | google-translate | GOOGLE_TRANSLATE_API_KEY | Google Cloud Translation API v2 (130+ languages) | | deepl | DEEPL_API_KEY | DeepL API with glossary support (30+ languages) | | microsoft-translator | MICROSOFT_TRANSLATOR_API_KEY | Azure Cognitive Services Translator (100+ languages) | | libretranslate | (self-hosted) | Self-hosted LibreTranslate (AGPL, free) |

Infrastructure — for custom or community-hosted endpoints:

| Method | Key | What It Does | |--------|-----|-------------| | api | (per provider) | Thin HTTP client for any REST endpoint |

# Force a specific method for one run
i18n-rosetta sync --method deepl

# Or configure per pair
{
  "pairs": {
    "en:fr": { "method": "deepl" },
    "en:ja": { "method": "openai", "model": "gpt-4o" },
    "en:crk": { "methodPlugin": "crk-coached-v1" }
  }
}

Note: Traditional MT methods (Google Translate, DeepL, Microsoft Translator, LibreTranslate) handle key-value pairs well but cannot safely translate Markdown content. For content-heavy projects, LLM methods are recommended — they explicitly shield code blocks, shortcodes, and interpolation variables.

Plugins

Plugins are pre-packaged translation recipes for specific language pairs. They're JSON manifests — not code — that tell rosetta which method to use, with what settings, and what quality has been benchmarked.

i18n-rosetta plugin install ./french-formal-v1/    # install from directory
i18n-rosetta plugin list                           # see installed plugins
i18n-rosetta plugin remove french-formal-v1        # uninstall
i18n-rosetta status                                # shows quality tiers + benchmarks

See docs/METHOD_PLUGIN_SPEC.md for the manifest format.

Commands

| Command | Purpose | |---------|---------| | init | Interactive setup wizard (or --yes for quick defaults) | | sync | Translate & sync all locale files | | watch | Auto-sync on file changes | | audit | Flag incomplete locales (CI gate) | | lint | Find hardcoded strings in source code | | wrap | Auto-wrap hardcoded strings in t() calls (with undo) | | seo | Generate hreflang, sitemap.xml, or JSON-LD schema | | integrity | Check for placeholder corruption, encoding, and ICU plural completeness | | status | Show pair configuration, methods, registers, and quality tiers | | provenance | Audit translation resource licensing | | plugin | Install, remove, or list method plugins | | fonts | Download web fonts for PUA script converters | | tm | Manage Translation Memory cache (stats, clear, per-locale) | | xliff | Export/import XLIFF 1.2 for professional translator review | | models | List available models for a provider (--method gemini) |

Run i18n-rosetta <command> --help for detailed help on any command.

Full reference: docs/CLI_REFERENCE.md

Configuration

Create i18n-rosetta.config.json or run i18n-rosetta init:

{
  "version": 3,
  "inputLocale": "en",
  "localesDir": "./locales",
  "model": "google/gemini-3.5-flash",
  "pairs": {
    "en:fr": { "qualityTier": "high" },
    "en:ja": { "method": "google-translate" }
  }
}

| Option | Default | Description | |--------|---------|-------------| | inputLocale | "en" | Source language code | | localesDir | "./locales" | Path to locale files | | contentDir | null | Hugo content directory (enables Markdown translation) | | format | "auto" | File format: json, toml, yaml, or auto | | model | "google/gemini-3.5-flash" | Default model (OpenRouter slug). Direct providers resolve their own default at runtime. Run rosetta models --method gemini to discover available models. | | defaultMethod | "llm" | Default translation method (overridden by --method flag) | | batchSize | 30 | Keys per translation batch | | pairs | {} | Per-pair method, model, and quality overrides |

Per-language overrides: Each language has a Language Card — one of 50 curated cards containing register presets, formality systems, typography rules, and method support flags. Cards use a two-tier architecture (runtime + reference) for performance at scale. Scaffold a new card with node scripts/generate-language-card.mjs <code>. Use preset keys as shorthand, or write custom register text:

{
  "languages": {
    "fr": "casual-tu",
    "ko": "formal-hapsyo",
    "crk": {
      "name": "Plains Cree",
      "register": "SRO syllabics with grammatical precision.",
      "model": "google/gemini-2.5-pro",
      "batchSize": 5,
      "maxRetries": 5,
      "script": "cans"
    }
  }
}

Zero-config mode: No config file? Rosetta auto-detects locale files, format, and target languages from your project.

Language values can be a preset key (e.g., "casual-tu"), custom register text, or an object (full control). Pair-level overrides in pairs take priority over language-level settings. Run npx i18n-rosetta init to browse available presets for each language.

Framework setup guides: docs/INTEGRATION_GUIDES.md

CLI Output

When you run sync, rosetta shows exactly what's happening:

i18n-rosetta v3.3.2

[INFO] Detected format: json (auto)
[INFO] Detected framework: Hugo
[INFO] Source: en.json (2,847 keys)
[INFO] Pairs: es-MX:llm, fr:deepl, it:llm
[INFO] Estimated translation cost:

  Pair       Method   Keys  Est. Cost
  ────────   ──────   ────  ─────────
  en:es-MX   llm      2847    ~$0.8400
  en:fr      deepl    2847    ~$0.5694
  en:it      llm      2847    ~$0.8400

  Total: ~$2.2494

[INFO] es-MX.json — 2,847 missing
     ████████████████████████████████ 2,847/2,847 keys
[INFO] fr.json — 2,847 missing
     ████████████████████████████████ 2,847/2,847 keys
[OK] Synced 5,694 keys total.

The progress bar updates in-place as each batch completes (~30 keys per update). Framework detection shows Hugo when contentDir is set. Format detection distinguishes (auto) from (config) to clarify how the format was resolved.

Output modes: --quiet suppresses informational output (errors and warnings only). --json emits machine-readable NDJSON for CI/CD pipelines.

Hardening

  • Exponential backoff — 3 retries with jitter on 429/5xx errors
  • 30s request timeout — AbortController prevents hanging
  • Response validation — only accepts keys that were sent for translation
  • Quality gate — catches hallucination loops, wrong-script output, length inflation, and source echoes
  • Retry cascade — on JSON parse failure, retries batch → half-batch → individual keys (budget-capped via maxRetries)
  • Translation Memory.rosetta/tm.json caches translations keyed by source text + locale + method; unchanged keys are served from cache on subsequent syncs, eliminating redundant API calls
  • Prompt caching — system/user message split enables provider-level caching, reducing token cost across batches
  • Terminology enforcement — coached translations are verified against dictionary terms after the LLM responds
  • Prototype pollution guard — blocks __proto__, constructor, prototype
  • Path containment — file writes validated to stay within configured directories
  • Block protection — code blocks, shortcodes, HTML shielded during content translation
  • Fail-loud architecture — translation failures always throw with actionable error messages, never silently write garbage
  • Post-sync verificationverify command re-reads written files and confirms translations are present, correct script, and placeholder-intact
  • Partial success — one failed batch doesn't block the rest

Testing

npm test                         # all tests
npm run test:unit                # core sync pipeline
npm run test:redteam             # adversarial edge cases
npm run test:format              # TOML/YAML adapters
npm run test:content             # Markdown content parser
npm run test:hugo                # full Hugo E2E
npm run test:lint                # hardcoded string detection
npm run test:pairs               # pair graph resolution
npm run test:methods             # translation method suite

Zero dependencies.

License

MIT