Introduction

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.

Copyright © 2026