https://github.com/guzzdev/i18n-parity
Validate parity of translation keys across locales: reports missing, empty, and extra keys with coverage (%).
https://github.com/guzzdev/i18n-parity
cicd i18n lint next-intl
Last synced: 3 months ago
JSON representation
Validate parity of translation keys across locales: reports missing, empty, and extra keys with coverage (%).
- Host: GitHub
- URL: https://github.com/guzzdev/i18n-parity
- Owner: guzzdev
- License: mit
- Created: 2025-12-15T20:29:04.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2025-12-19T03:56:51.000Z (6 months ago)
- Last Synced: 2025-12-22T00:53:08.554Z (6 months ago)
- Topics: cicd, i18n, lint, next-intl
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/i18n-parity
- Size: 27.3 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# i18n-parity
Validate parity of translation keys across locales: reports missing, empty, and extra keys with coverage (%)
[](https://www.npmjs.com/package/i18n-parity)
[](LICENSE)
> [!NOTE]
> 1. This tool is an open-source version derived from a private commercial solution used internally.
>
> 2. Built for [next-intl](https://next-intl.dev/) but works with any JSON-based i18n setup.
Feel free to contribute or contact me.
## Features
- Missing keys detection
- Empty value detection
- Extra keys detection
- Coverage metrics
- CI/CD
- Fast & lightweight
## Install
```bash
npm i -D i18n-parity
bun add -d i18n-parity
```
## Usage
```bash
i18n-parity --ref en --dir ./src/locales
```
### Options
| Flag | Description | Default |
|------|-------------|---------|
| `--ref` | Reference locale (filename w/o .json) | `fr` |
| `--dir` | Directory with locale JSON files | `./src/locales` |
| `--format` | `table` or `json` | `table` |
| `--fail-on` | Exit with error on: `missing`, `empty`, `extra` | none |
### Examples
```bash
# Basic usage
i18n-parity --ref en --dir ./locales
# JSON output for CI
i18n-parity --format json
# Fail on missing or empty translations
i18n-parity --fail-on missing,empty
```
Output looks like this:
```
┌─────────┬──────────┬─────────┬───────┬───────┐
│ locale │ coverage │ missing │ empty │ extra │
├─────────┼──────────┼─────────┼───────┼───────┤
│ es │ 85.71% │ 1 │ 1 │ 1 │
│ de │ 100% │ 0 │ 0 │ 0 │
└─────────┴──────────┴─────────┴───────┴───────┘
[es] Missing keys (1):
- navigation.compass
[es] Empty keys (1):
- commands.anchor
```
## API
```typescript
import { checkI18n, diff } from "i18n-parity";
const results = await checkI18n("en", "src/locales");
console.log(results[0].coveragePercent);
```
The `DiffResult` type:
```typescript
type DiffResult = {
locale: string;
totalLeafKeys: number;
presentLeafKeys: number;
coveragePercent: number;
missingKeys: string[];
emptyKeys: string[];
extraKeys: string[];
}
```
## CI Setup
GitHub Actions:
```yaml
- uses: oven-sh/setup-bun@v2
- run: bun install
- run: bun i18n-parity --ref en --dir ./locales --fail-on missing,empty
```
## License
[MIT](LICENSE)