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

i18n-smell-detector

v0.9.1

Published

Find copied locale values, placeholder mismatches, and hardcoded user-visible strings.

Readme

i18n-smell-detector

npm version CI Socket Badge License: MIT

Find localization issues that key coverage checks miss.

i18n-smell-detector checks locale files for copied base-locale values and placeholder mismatches. It can also scan Vue, JavaScript, TypeScript, JSX, and TSX source for hardcoded user-visible strings.

The classifier is deterministic and conservative. Start with --fail-on none, review the report, then tune allowlists before enforcing CI.

Features

  • Detect copied base-locale values.
  • Detect missing or extra placeholders.
  • Detect hardcoded user-visible strings in Vue, JS, TS, JSX, and TSX.
  • Output console, JSON, Markdown, SARIF, or HTML reports.
  • Support baselines for gradual adoption.
  • Publish TypeScript types and a small public API for integrations.

Install

npm install -D i18n-smell-detector

Quick Start

npx i18n-smell-detector init
npx i18n-smell-detector check --config i18n-smell.config.mjs --fail-on none

init creates i18n-smell.config.mjs. When it finds locale JSON files in src/locales, src/i18n, locales, or i18n, it writes them into the config automatically.

A typical config:

export default {
  baseLocale: 'en',
  locales: {
    en: './src/locales/en.json',
    zh: './src/locales/zh.json',
    'zh-Hans': './src/locales/zh-Hans.json',
  },
  source: ['src/**/*.{vue,js,jsx,ts,tsx}'],
  failOn: 'none',
};

Locale keys that contain -, such as 'zh-Hans', must be quoted.

With ignoreSameLanguageFamily enabled, locale tags are compared by language, inferred script, and explicitly declared region. Different scripts are checked normally, two different explicit regions are reported at low severity, and otherwise matching language and script are ignored. The last case includes comparisons where one or both locale tags do not explicitly declare a region.

Commands

npx i18n-smell-detector check --config i18n-smell.config.mjs
npx i18n-smell-detector check-identical --config i18n-smell.config.mjs
npx i18n-smell-detector check-hardcoded --config i18n-smell.config.mjs
npx i18n-smell-detector check-placeholders --config i18n-smell.config.mjs

Common options:

| Option | Description | | --------------------- | -------------------------------------------------- | | -c, --config <path> | Use a specific config file. | | --format <format> | console, json, markdown, sarif, or html. | | --output <path> | Write the full report to a file. | | --fail-on <level> | high, medium, low, or none. | | --baseline <path> | Suppress findings stored in a baseline file. | | --update-baseline | Write current findings to the baseline file. | | --include-ignored | Include ignored findings in the report. | | --debug | Print stack traces for troubleshooting. | | -V, --version | Print the installed package version. |

Configure precise JavaScript and TypeScript message sinks when messages flow through application-specific APIs:

export default {
  hardcoded: {
    sinks: {
      calls: [{ callee: 'notify', arguments: [0] }],
      assignments: ['error.value'],
      properties: ['summary', 'detail'],
    },
  },
};

Configured sinks recursively inspect conditional, logical, parenthesized, and TypeScript wrapper expressions. An interpolated template such as `Delete ${item.name}?` is reported once as Delete {item.name}?, with the raw template and interpolation ranges available in JSON and SARIF output.

Categorize values that must intentionally remain identical across locales:

export default {
  doNotTranslate: [
    {
      values: ['PRODUCT_X', /^MODEL-\d+$/],
      category: 'product-name',
      reason: 'Official product terminology',
      owner: 'localization-team',
    },
    {
      keys: [/^technical\./],
      category: 'technical-term',
      reason: 'Protocol terminology',
    },
  ],
  hardcoded: {
    technicalTerms: ['PROTOCOL_X', /^MODEL-\d+$/],
  },
};

doNotTranslate applies to identical-translation findings and preserves auditable suppression metadata. Hardcoded findings expose confidence separately from severity; failOn continues to use severity only.

Reports

npx i18n-smell-detector check --format markdown --output reports/i18n-smell.md
npx i18n-smell-detector check --format html --output reports/i18n-smell.html
npx i18n-smell-detector check --format sarif --output reports/i18n-smell.sarif

Use --format json for automation and --format sarif for code-scanning tools.

CI

Start in reporting mode:

npx i18n-smell-detector check --config i18n-smell.config.mjs --fail-on none

After tuning allowlists and baselines, enforce a severity threshold:

npx i18n-smell-detector check --config i18n-smell.config.mjs --fail-on high

TypeScript API

The package exposes types and a small public API from the package root:

import { checkIdenticalTranslations, severityRank } from 'i18n-smell-detector';
import type { DetectorConfigInput, DetectorIssue, CheckResult } from 'i18n-smell-detector';

Documentation

Full documentation lives in the GitHub Wiki:

Development

npm install
npm run typecheck
npm test
npm run check
npm run benchmark

License

MIT