lacspace-i18n

Locale linter — ICU, .po convert, auto-sync, coverage.

● Live · v0.2.0npm ↗Source ↗
terminal
npx lacspace-i18n ./locales
What it does

Everything, in one command

Translations rot quietly — a new en key never lands in ne, a translator drops a placeholder, a deleted base key lingers in ten files, dead keys pile up. lacspace-i18n audits JSON (nested or flat), a YAML subset, and .properties in both en.json and namespaced en/common.json layouts, cross-references keys against your source for dead/undefined usages, checks {name}/{{name}}/printf/ICU placeholder consistency, and can sort, fill and prune files in place — all locally, no API key, no telemetry.

Features

What's inside

Coverage & diff

Per-locale % plus missing / extra / empty / identical keys against a base.

Interpolation & ICU check

Same placeholder set across locales; catches dropped {count} and malformed plurals.

Dead & undefined keys

Scan t()/<Trans>/$t in source to find unused and never-defined keys.

Multi-format

JSON, a YAML subset, and .properties, flat or namespaced, compared as one key space.

Sort / fill / prune

Normalize files, add missing base keys with a marker, drop stale extras.

CI-ready

--fail-on missing,icu,undefined exits non-zero; --json / -f md output.

Keyless & zero-dep

No service, no parser to install, nothing sent anywhere.

ICU MessageFormat validation

Parses plural/select/number/date messages and flags malformed structure, argument mismatches and missing 'other' branches.

gettext .po conversion

Read/write .po alongside JSON, YAML and .properties, and convert between any pair.

Auto-sync translations

Fill each locale with the base's missing keys (marker or base value) without overwriting existing translations.

Coverage CI gate

--min N exits non-zero when a locale falls below a threshold; fill markers excluded from the count.

How to use

Copy, paste, done

Real commands and snippets — from a one-liner to the typed library.

Full audit
terminal
npx lacspace-i18n ./locales --base en

Coverage bars + every problem class.

What's a translator missing
terminal
npx lacspace-i18n missing ./locales --json

{ "ne": ["nav.about"] }

Dead / undefined keys
terminal
npx lacspace-i18n unused ./locales --src ./src --ignore "admin.*"

Cross-references code usage.

CI gate
terminal
npx lacspace-i18n check ./locales --fail-on missing,icu,undefined

Exits 1 on problems.

Sync files
terminal
npx lacspace-i18n sort ./locales --fill="[TODO]" --prune --write

Sort, fill, prune in place.

Convert gettext .po to JSON
terminal
npx lacspace-i18n convert messages.po -o en.json

Formats inferred from extensions; --from/--to override.

Auto-sync locales to the base
terminal
npx lacspace-i18n sync ./locales --from-base --write

Fills missing keys from base values; existing translations untouched.

Deep ICU check
terminal
npx lacspace-i18n icu ./locales

Catches plurals missing 'other' and dropped arguments a plain diff misses.

Gate CI on coverage
terminal
npx lacspace-i18n coverage ./locales --min 90

Exits 1 if any locale is below 90% (markers excluded).

Good for

What people build with it

✓ Block a release when a locale is incomplete or an ICU plural is broken

✓ Hand a translator the exact missing-key list

✓ Prune keys deleted from the base out of every locale

✓ Catch dropped {name}/{count} interpolations in PR review

Start now

Run lacspace-i18n today

Free, open-source, no API keys. It's a CLI and a typed library.

terminal
npx lacspace-i18n ./locales