Why the-i18n-kit
The Problem
Translation files are data no compiler checks. Nothing fails when a key is referenced and never defined, and nothing fails when a key is defined and nothing references it. Both accumulate:
- A new component needs its key created in every locale file, by hand.
- Deleted components leave keys behind, and nobody can prove which are safe to remove, so nobody removes any.
- Renaming a key means editing every locale file and every call site.
- An agent writing
$t('booking.confirm.title')cannot tell what already exists without reading thousands of lines of JSON into its context window.
The kit turns those into operations: targeted reads that return the keys you asked for, writes applied across every locale in one call, and a scan that reports why a key looks unused before offering to delete it.
Who It Is For
You work with an AI agent. Results are JSON, large results divert to a file and return a summary, and failures carry codes an agent branches on. The agent contract is the whole surface, in one page.
You maintain i18n in a large monorepo. You have layers — scoped locale
directories, whether those are Nuxt layers, workspace packages, a shared UI
library, or one app among several — and the same key can mean different things
in different ones. What you need is a reason to trust a deletion. The kit builds
a consumer graph — from your Nuxt layers, your package manager workspace, or a
declaration in your config — and counts usage per consuming app, so a key used in
app-shop does not protect the same key name in app-admin. See
layers and the consumer graph.
Who Does Not Need This
A single-locale project with one locale file and a few dozen keys. One command still earns its place there:
npx -y @the-i18n-kit/cli@latest check
check reports keys referenced in source and defined in no locale layer the
using app consumes — the ones that render as the raw key string in production —
and exits 2 when it finds any. It needs no config file. Dynamically built keys
are reported separately and never fail the run.
Next to an i18n Linter
If you run eslint-plugin-i18next or vue-i18n's ESLint rules, keep them. A
linter inspects call sites as you type: no bare user-facing strings, no missing
namespace. It reads one file at a time and has no project model, so it cannot
answer which keys nothing references, which apps consume a shared layer, or move
a key across thirty locale files at once. The kit reads your source; it never
rewrites call sites, so the two do not conflict.
The kit's own ESLint plugin covers the third case: authoring idioms that blind the orphan scanner, and keys that do not exist for the app using them.