npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

translate-lint

v1.10.2

Published

Simple tools for checking translate keys in the whole app that uses regexp. Support for popular libraries and frameworks

Readme

translate-lint

Simple tools for checking translate keys in the whole app that uses regexp. Support for popular libraries and frameworks

semantic npm download npm

for desktop use ngx-translate-editor

Table of Contents

Background

There are a lot of translation keys in the whole app. This repository contains a proposal to check all translation keys in the whole app which should exist in all languages files.

Support

| Library | Preset | Framework | |------------------------------------------------------------------|-------------------------|-----------| | ngx-translate | angular-ngx-translate | Angular | | transloco | transloco | Angular | | react-i18next | react-i18next | React | | react-intl | react-intl | React | | lingui | lingui-js | React | | next-intl | next-intl | Next.js | | next-i18next | next-i18next | Next.js | | vue-i18n | vue-i18n | Vue | | i18next-vue | i18next-vue | Vue | | fluent-vue | fluent-vue | Vue | | @nuxtjs/i18n | nuxtjs-i18n | Nuxt.js | | svelte-i18n | svelte-i18n | Svelte | | next-translate | next-translate | Next.js | | remix-i18next | remix-i18next | Remix | | sveltekit-i18n | sveltekit-i18n | SvelteKit | | solid-i18n | solid-i18n | Solid.js | | qwik-speak | qwik-speak | Qwik | | i18next | i18next | Universal | | i18n | i18n-node | Node.js | | lit-translate | lit-translate | Lit |

Installation

NPM

npm install translate-lint -g

Usage

CLI

Run translate-lint against your project and language files:

translate-lint -p './src/app/**/*.{html,ts,resx}' -l './src/assets/i18n/*.{json,yaml,yml}' -f angular-ngx-translate

NOTE: For project and languages options need to include file types like on the example.

Flags


Usage: translate-lint [options]

Simple tools for checking translate keys in the whole app that uses regexp.
Support for popular libraries and frameworks

Options:
  -f, --frameworkPreset [enum] (required)
          Preset of frameworks and libraries
          Possible Values: <angular-ngx-translate|lingui-js|next-intl|react-intl|react-i18next|vue-i18n|fluent-vue|i18next-vue|transloco|next-i18next|nuxtjs-i18n|svelte-i18n|next-translate|i18next|remix-i18next|sveltekit-i18n|solid-i18n|qwik-speak|i18n-node|lit-translate>
  -p, --project [glob]
          The path to project folder. (default: './src/app/**/*.{html,ts,resx}')
          Possible Values: <relative path|absolute path>
  -l, --languages [glob]
          The path to languages folder. (default: './src/assets/i18n/*.{json,yaml,yml}')
          Possible Values: <relative path|absolute path|URL>
  --kv, --keysOnViews [enum]
          Described how to handle the error of missing keys on view. (default: "error")
          Possible Values: <disable|warning|error>
  --zk, --zombieKeys [enum]
          Described how to handle the error of zombies keys. Zombie keys are keys that doesn't exist on any languages file but exist on project, or exist languages but doesn't exist on project. (default: "warning")
          Possible Values: <disable|warning|error>
  --ek, --emptyKeys [enum]
          Described how to handle empty value on translate keys. Empty keys are keys that doesn't have any value on languages files. (default: "warning")
          Possible Values: <disable|warning|error>
  -i, --ignore [glob]
          Ignore projects and languages files
          Possible Values: <relative path|absolute path>
  --maxWarning [glob]
          Maximum number of warnings allowed across all files. If the total warning count exceeds this value, the run is treated as a failure (exit code 1). (default: 0)
          Possible Values: <number>
  --mk, --misprintKeys [enum]
          Try to find matches with misprint keys on views and languages keys. Coefficient: 0.9. Can be longer process!! (default: "disable")
          Possible Values: <disable|warning|error>
  --ds, --deepSearch [enum]
          Add each translate key to global regexp end try to find them on project. Can be longer process!! (default: "disable")
          Possible Values: <disable|enable>
  --mc, --misprintCoefficient [number]
          Coefficient for misprint option can be from 0 to 1.0. (default: 0.9)
  -c, --config [path]
          Path to config via JSON or JS file
          Possible Values: <relative path|absolute path>
  --fz, --fixZombiesKeys [boolean]
          Auto fix zombies keys on languages files
  --dk, --duplicateKeys [enum]
          Detect keys that are duplicated within the same language file. (default: "disable")
          Possible Values: <disable|warning|error>
  --mt, --missingTranslations [enum]
          Detect keys that exist in one language file but are missing in others. (default: "disable")
          Possible Values: <disable|warning|error>
  --fm, --fixMissingKeys [boolean]
          Auto-add missing keys to all language files with an empty value
  --knc, --keyNamingConvention [enum]
          Enforce a naming convention for translation key segments. (default: "disable")
          Possible Values: <disable|warning|error>
  --kncf, --keyNamingConventionFormat [enum]
          Naming format used by the keyNamingConvention rule. (default: "SCREAMING_SNAKE")
          Possible Values: <SCREAMING_SNAKE|camelCase|snake_case|kebab-case|PascalCase>
  --ft, --format [enum]
          Output format for lint results. (default: "stylish")
          Possible Values: <stylish|json|junit>
  --cv, --coverage [enum]
          Described how to handle the error when project coverage (% of language keys actually used, see --minCoverage) drops below the configured minimum. (default: "disable")
          Possible Values: <disable|warning|error>
  --mcv, --minCoverage [number]
          Minimum percentage of language keys that must be used in the project, checked by the --coverage rule. (default: 80)
  --dv, --duplicateValues [enum]
          Detect identical translation values reused under different keys in the same language file. (default: "disable")
          Possible Values: <disable|warning|error>
  --uv, --untranslatedValues [enum]
          Detect values that are identical to the same key's value in --referenceLocale — a sign of a forgotten translation. (default: "disable")
          Possible Values: <disable|warning|error>
  --rl, --referenceLocale [glob]
          Substring matched (case-insensitive) against language file names to pick the reference locale used by --untranslatedValues, e.g. "en". (default: none)
  --cskc, --caseSensitiveKeyCollision [enum]
          Detect keys in the same language file that differ only by letter case (e.g. 'Button.Save' vs 'button.save'). (default: "disable")
          Possible Values: <disable|warning|error>
  --sk, --sortKeys [enum]
          Detect translation keys that are not sorted within their language file, at every nesting level (see --sortBy). (default: "disable")
          Possible Values: <disable|warning|error>
  --sb, --sortBy [enum]
          Sort order used by the sortKeys rule. (default: "asc")
          Possible Values: <asc|desc>
  --fsk, --fixSortKeys [boolean]
          Auto-sort keys in JSON language files that violate the sortKeys rule
  --vc, --variableConsistency [enum]
          Detect interpolation variables (e.g. '{name}', '{{count}}', '%s') that don't match across language files for the same key. (default: "disable")
          Possible Values: <disable|warning|error>
  --mvl, --maxValueLength [enum]
          Detect translation values longer than --valueLength characters. (default: "disable")
          Possible Values: <disable|warning|error>
  --vl, --valueLength [number]
          Maximum allowed translation value length, checked by the maxValueLength rule. (default: 200)
  --fmvl, --fixMaxValueLength [boolean]
          Auto-truncate values in JSON language files that exceed --valueLength
  --nhiv, --noHtmlInValues [enum]
          Detect HTML markup (e.g. '<b>text</b>') inside translation values. (default: "disable")
          Possible Values: <disable|warning|error>
  --fnhiv, --fixNoHtmlInValues [boolean]
          Auto-strip HTML markup from values in JSON language files
  --htc, --htmlTagConsistency [enum]
          Detect an inconsistent set of HTML tags for the same key across language files. (default: "disable")
          Possible Values: <disable|warning|error>
  --be, --brokenEncoding [enum]
          Detect mojibake artifacts (e.g. 'é', '’') left by double UTF-8 encoding in translation values. (default: "disable")
          Possible Values: <disable|warning|error>
  --vekn, --valueEqualsKeyName [enum]
          Detect translation values that are identical to their own key name. (default: "warning")
          Possible Values: <disable|warning|error>
  --lfnc, --localeFileNamingConvention [enum]
          Enforce a naming convention for language file names. (default: "disable")
          Possible Values: <disable|warning|error>
  --lfnf, --localeFileNamingFormat [enum]
          Naming format used by the localeFileNamingConvention rule. (default: "xx-XX")
          Possible Values: <xx|xx-XX|XX-xx|xx_XX>
  --dlf, --duplicateLocaleFile [enum]
          Detect language files that are byte-for-byte identical to another language file. (default: "disable")
          Possible Values: <disable|warning|error>
  --elf, --emptyLocaleFile [enum]
          Detect language files that parse successfully but contain no translation keys. (default: "disable")
          Possible Values: <disable|warning|error>
  --init [boolean]
          Interactively generate a translate-lint config file

  -v, --version                          Print current version of translate-lint
  -h, --help                             display help for command


Examples:

    $ translate-lint -p './src/app/**/*.{html,ts,resx}' -l './src/assets/i18n/*.json' -f angular-ngx-translate
    $ translate-lint -p './src/app/**/*.{html,ts,resx}' -zk disable -kv error -f react-i18next
    $ translate-lint -p './src/app/**/*.{html,ts,resx}' -i './src/assets/i18n/EN-us.json, ./src/app/app.*.{json}' -f react-intl
    $ translate-lint -p './src/app/**/*.{html,ts,resx}' -l 'https://8.8.8.8/locales/EN-eu.json' -f lingui-js

NOTE: For project and languages options need to include file types like on the example.

Option resolution order

Every option follows the same precedence, uniformly: explicit CLI flag > config file (--config) > built-in default. None of the flags above carry a hidden CLI-side default that would silently override a value you set in the config file — if you omit a flag on the CLI, the config file (and then the built-in default) decides.

Output format

Three formats are available via --format (--ft):

| Format | Description | |--------|-------------| | stylish | Human-readable colored output (default) | | json | Machine-readable JSON — ideal for CI artifacts | | junit | JUnit XML — consumed by GitHub Actions, Jenkins, GitLab CI test reporters |

JSON format:

translate-lint -p './src/**/*.ts' -l './locales/*.json' -f react-i18next --format json
{
  "errors": [
    {
      "key": "AUTH.LOGIN",
      "errorType": "error",
      "rule": "keysOnViews",
      "file": "src/app/login.ts",
      "message": ["Key: 'AUTH.LOGIN' doesn't exist in 'src/app/login.ts'"]
    }
  ],
  "summary": {
    "total": 3,
    "errors": 2,
    "warnings": 1
  },
  "coverage": {
    "totalKeys": 120,
    "usedKeys": 105,
    "unusedKeys": 15,
    "percentage": 87.5
  },
  "stats": {
    "viewFiles": 12,
    "languageFiles": 3,
    "elapsedMs": 342
  }
}

Default Configuration

Default JSON Config is:

{
    "rule": {
        "keysOnViews": {
            "type": "error"
        },
        "zombieKeys": {
            "type": "warning",
            "fix": false
        },
        "emptyKeys": {
            "type": "warning"
        },
        "misprintKeys": {
            "type": "disable",
            "coefficient": 0.9,
            "ignored": []
        },
        "deepSearch": {
            "type": "disable"
        },
        "maxWarning": 0,
        "ignoredKeys": [ "IGNORED.KEY.(.*)" ],
        "customRegExpToFindKeys": [ "(?<=marker\\(['\"])([A-Za-z0-9_\\-.]+)(?=['\"]\\))"],
        "namespaceKeys": {
            "type": "disable",
            "delimiter": ".",
            "namespaces": {},
            "globalNamespaces": [],
            "ignoreInFolders": []
        },
        "maxKeyDepth": {
            "type": "disable",
            "depth": 4
        },
        "duplicateKeys": {
            "type": "disable"
        },
        "missingTranslations": {
            "type": "disable",
            "fix": false
        },
        "keyNamingConvention": {
            "type": "disable",
            "format": "SCREAMING_SNAKE"
        },
        "coverage": {
            "type": "disable",
            "min": 80
        },
        "duplicateValues": {
            "type": "disable"
        },
        "untranslatedValues": {
            "type": "disable",
            "referenceLocale": ""
        },
        "caseSensitiveKeyCollision": {
            "type": "disable"
        },
        "sortKeys": {
            "type": "disable",
            "sortBy": "asc",
            "fix": false
        },
        "variableConsistency": {
            "type": "disable"
        },
        "maxValueLength": {
            "type": "disable",
            "length": 200,
            "fix": false
        },
        "noHtmlInValues": {
            "type": "disable",
            "fix": false
        },
        "htmlTagConsistency": {
            "type": "disable"
        },
        "brokenEncoding": {
            "type": "disable"
        },
        "valueEqualsKeyName": {
            "type": "warning"
        },
        "localeFileNamingConvention": {
            "type": "disable",
            "format": "xx-XX"
        },
        "duplicateLocaleFile": {
            "type": "disable"
        },
        "emptyLocaleFile": {
            "type": "disable"
        }
    },
    "fetch": {
        "requestQuery": "",
        "requestHeaders": {},
        "responseQuery": ""
    },
    "project": "./src/app/**/*.{html,ts}",
    "languages": "./src/assets/i18n/*.{json,yaml,yml}",
    "frameworkPreset": "angular-ngx-translate"
}

JS Config should have default export via object like config. See example:

Example JS config is:


const config = {
    rule: {
        keysOnViews: {
            type: "error",
        },
        zombieKeys: {
            type: "warning",
            fix: false,
        },
        emptyKeys: {
            type: "warning",
        },
        misprintKeys: {
            type: "warning",
            coefficient: 0.9,
            ignored: [],
        },
        deepSearch: {
            type: "disable",
        },
        maxWarning: 0,
        ignoredKeys: [],
        customRegExpToFindKeys: [],
        namespaceKeys: {
            type: 'error',
            delimiter: '.',       // use ':' for react-i18next (e.g. t('bonus:TITLE'))
            namespaces: {
                'bonus':      ['apps/bonus', 'apps/bonus-detail'],
                'registration': ['apps/registration', 'apps/auth'],
            },
            globalNamespaces: ['g', 'form', 'nav', 'popup'],
            ignoreInFolders: ['sandbox-component-kit'],
        },
        maxKeyDepth: {
            type: "disable",
            depth: 4,
        },
        duplicateKeys: {
            type: "disable",
        },
        missingTranslations: {
            type: "disable",
            fix: false,
        },
        keyNamingConvention: {
            type: "disable",
            format: "SCREAMING_SNAKE",  // SCREAMING_SNAKE | camelCase | snake_case | kebab-case | PascalCase
        },
        coverage: {
            type: "disable",
            min: 80,
        },
        duplicateValues: {
            type: "disable",
        },
        untranslatedValues: {
            type: "disable",
            referenceLocale: "",   // e.g. "en" to match EN-us.json / en.json / en-GB.json
        },
        caseSensitiveKeyCollision: {
            type: "disable",
        },
        sortKeys: {
            type: "disable",
            sortBy: "asc",   // "asc" | "desc"
            fix: false,
        },
        variableConsistency: {
            type: "disable",
        },
        maxValueLength: {
            type: "disable",
            length: 200,
            fix: false,
        },
        noHtmlInValues: {
            type: "disable",
            fix: false,
        },
        htmlTagConsistency: {
            type: "disable",
        },
        brokenEncoding: {
            type: "disable",
        },
        valueEqualsKeyName: {
            type: "warning",
        },
        localeFileNamingConvention: {
            type: "disable",
            format: "xx-XX",   // "xx" | "xx-XX" | "XX-xx" | "xx_XX"
        },
        duplicateLocaleFile: {
            type: "disable",
        },
        emptyLocaleFile: {
            type: "disable",
        },
    },
    fetch: {
        requestQuery: "",
        requestHeaders: {},
        responseQuery: "",
        get: async () => {
            const requestOne = fetch('https://8.8.8.8/locales/EN-eu.json');
            const requestTwo = fetch('https://8.8.8.8/locales/EN-us.json');
            const result = await Promise.all([requestOne, requestTwo]).then(async ([responseOne, responseTwo]) => {
                return {
                    ...(await responseOne.json()),
                    ...(await  responseTwo.json())
                }
            });
            // NOTE: result should contains only translation keys. Example
            // {
            //   "translation.key": "value"
            // }
            return result;
        }
    },
    project: "./src/app/**/*.{html,ts}",
    languages: "./src/assets/i18n/*.{json,yaml,yml}",
    frameworkPreset: "angular-ngx-translate",
}

export default config;

Init

Run the interactive config generator to create a translate-lint.config.json (or .js) file in the current directory:

translate-lint --init

After generation, pass the file to the linter via --config:

translate-lint --config ./translate-lint.config.json

TypeScript

translate-lint can also be used programmatically — the TranslateLint class, all rule config interfaces, and the framework preset registry are exported from the package. See docs/rules/README.md for a full, up-to-date example.

Rules

translate-lint ships with the following rules. See docs/rules/README.md for how each one works, its config options, CLI flags, and example error messages:

Contribute

You may contribute in several ways like requesting new features, adding tests, fixing bugs, improving documentation or examples. Please check our contributing guidelines.

Used By

Here can be your extensions:

  • ngx-translate-editor - Simple GUI for CRUD translate keys of ngx-translate, which included ngx-translate-lint
  • 121 Platform - 121 is an open source platform for Cash based Aid built with Digital Identity & Local/Global Financial service partners.

License

MIT