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

eslint-plugin-no-hardcoded-strings

v1.1.0

Published

ESLint plugin that forbids rendering hardcoded user-visible strings in JSX.

Readme

eslint-plugin-no-hardcoded-strings 🌐

Version

Detect hardcoded user-visible strings rendered in JSX and common user-visible JSX attributes, and require them to flow through your translation layer instead.

The rule catches plain JSX text, string literals rendered through JSX expressions, common user-visible attributes such as placeholder, alt, title, and aria-label, plus identifiers that resolve to hardcoded strings or disallowed helper calls.

What it catches

<div>Hello world</div>; // flagged
<div>{"Hello world"}</div>; // flagged
<div>{formatLabel("Hello world")}</div>; // flagged
<input placeholder="Name" />; // flagged
<button aria-label={"Save changes"} />; // flagged

const label = "Hello world";
<div>{label}</div>; // flagged

let placeholder = t("form.name");
placeholder = "Full name";
<input placeholder={placeholder} />; // flagged

const translatedLabel = t("home.title");
<div>{translatedLabel}</div>; // allowed

<div>{i18n.t("home.title")}</div>; // allowed

Installation

npm install --save-dev eslint eslint-plugin-no-hardcoded-strings

Usage

Flat config (eslint.config.js)

const noHardcodedStrings = require("eslint-plugin-no-hardcoded-strings");

module.exports = [
  noHardcodedStrings.configs["flat/recommended"],
  {
    rules: {
      "no-hardcoded-strings/no-hardcoded-strings": [
        "warn",
        {
          allowedFunctionNames: ["t", "translate", "i18n"],
          ignoreStrings: ["OK", "Cancel"],
          ignorePatterns: [/^[0-9\\s:-]+$/],
        },
      ],
    },
  },
];

Legacy config (.eslintrc.cjs)

module.exports = {
  plugins: ["no-hardcoded-strings"],
  rules: {
    "no-hardcoded-strings/no-hardcoded-strings": [
      "warn",
      {
        allowedFunctionNames: ["t", "translate", "i18n"],
        ignoreStrings: ["OK", "Cancel"],
        ignorePatterns: [/^[0-9\\s:-]+$/],
      },
    ],
  },
};

Options

| Option | Type | Default | Description | | --- | --- | --- | --- | | allowedFunctionNames | string[] | ["t"] | Function or member-property names allowed to render translation keys | | ignoreStrings | string[] | [] | Exact rendered strings to allow | | ignorePatterns | (RegExp \| string)[] | [] | Regexes or regex source strings used to allow matching rendered strings |

ignorePatterns is most ergonomic in JS or TS ESLint config files where RegExp values are supported directly. In JSON-style config, use regex source strings such as ^[0-9\\s:-]+$.

The variable analysis is intentionally conservative: the rule follows simple declarations and simple reassignments before render, but it does not try to solve full control-flow or interprocedural data flow.

Development

This repository uses npm, not Yarn or pnpm.

Useful commands:

npm test
npm run build
npm run verify

CI also runs the rule tests against ESLint 8.57.1, 9.39.4, and 10.2.0 so the advertised compatibility range is checked continuously.

Commits are expected to use conventional commit messages. Local raw git commit is blocked by Husky on purpose; use the interactive helper instead:

npm run commit

That helper is intentionally a small local script instead of commitizen to keep transitive maintenance and vulnerability surface low.

Release workflow

Releases are automated with semantic-release in GitHub Actions.

  • CI runs npm ci and npm run verify.
  • Releases run on pushes to main or master, plus manual workflow dispatch.
  • The workflow is designed for protected branches and does not rely on pushing version or changelog commits back to git.
  • semantic-release still needs enough repository permission to create and push the release tag. If your branch protection or rulesets block the default GITHUB_TOKEN push check, allow the workflow actor to bypass that rule or use a dedicated automation token for GitHub release/tag operations.
  • Git tags, npm releases, and GitHub Releases are the release source of truth.
  • Because of that, the package.json version committed on main can lag behind the latest published version.
  • The release workflow is set up for npm Trusted Publishing via GitHub Actions OIDC. Once the npm package is configured for trusted publishing, no long-lived NPM_TOKEN should be required.
  • Because this package was already published before semantic-release was introduced, the existing 1.0.0 release should be bootstrapped with a v1.0.0 git tag on the original release commit before the first automated release is cut.

You can preview the release process locally with:

npm run release:dry-run

That dry run still needs network access and repository credentials for the GitHub verification steps.