ESLint Plugin

Install and Presets

@the-i18n-kit/eslint-plugin-vue moves two classes of i18n feedback from CI into the editor: authoring idioms that blind the orphan scanner, and keys that do not exist for the app using them. The rules and the layer-aware factory each have their own page.

The plugin is purely additive to the scanner. The scan keeps every safety net — the candidate net, wide dynamic patterns, the uncertain classification — because remove-orphans must stay safe on code the lint never saw: old commits, generated files, repos that never adopt the plugin. What the rules change is how much work those nets do, not whether they exist.

1. Install the Package

pnpm add -D @the-i18n-kit/eslint-plugin-vue

It requires ESLint ^9.10.0 (flat config only) and Node 18 or newer. One peer is optional and only needed for the layer-aware factory: @intlify/eslint-plugin-vue-i18n (^3.0.0 || ^4.0.0), whose no-missing-keys the factory configures. The two authoring rules work without it.

2. Spread a Preset

The default export carries the plugin and two presets as ordinary flat-config arrays:

eslint.config.mjs
import i18nKit from '@the-i18n-kit/eslint-plugin-vue'

export default [
  ...i18nKit.configs.recommended,
]

Both presets register the plugin under the @the-i18n-kit/vue prefix and apply to **/*.vue, **/*.ts, **/*.js and **/*.mjs. They differ in one severity:

Rulerecommendedstrict
literal-key-prefixerrorerror
runtime-key-needs-declared-namespacewarnerror

Overriding a severity is plain flat-config precedence — a later entry wins:

eslint.config.mjs
import i18nKit from '@the-i18n-kit/eslint-plugin-vue'

export default [
  ...i18nKit.configs.recommended,
  {
    rules: {
      '@the-i18n-kit/vue/runtime-key-needs-declared-namespace': 'error',
    },
  },
]

3. Triage, Then Promote

The runtime-key rule is a warning in recommended deliberately. On its first real-world adoption run it found 81 sites, dominated by option-list callbacks like (o) => t(o.label) — calls whose keys the scanner's candidate net already protects. Shipping those 81 as errors on day one teaches a team to blanket-disable the rule, which protects nothing.

The intended path:

  1. Run with recommended and read the warnings.
  2. Annotate the genuinely wire-driven calls — keys that arrive from a backend or database — as described in the annotation workflow.
  3. Promote the rule to error (or switch to strict) once the remaining warnings are decisions rather than a backlog.

For a one-off exception, a standard eslint-disable comment is the escape hatch. There is no parallel suppression system.

Limits

  • Vue only, by decision. The rules recognize the vue-i18n call family — t/te/tc where they resolve to a vue-i18n binding, $t/$te/$tc, composer instances from useI18n(), nuxtApp.$i18n.t(...) — in plain Vue or Nuxt. The React call families are not recognized: next-intl's namespace-relative keys would need React-specific judgment, and "works for React except the main feature" is a promise nobody can rely on. React projects keep the CLI's full scan coverage in CI.
  • The plugin lints code, not catalogs. Duplicate values, unused keys and translation completeness stay with find-duplicates, the orphan scan and missing.

Next

  • The Rules — what each rule fires on, what it deliberately ignores, and the annotation workflow.
  • Layer-Aware Missing Keys — per-app key existence via layerAware(), and the zero-config Nuxt path.
Copyright © 2026