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

@stryder-works/coding-standards

v0.4.1

Published

Shared coding standards lint kit for Stryder-Works

Readme

@stryder-works/coding-standards

Shared coding standards lint kit for Stryder-Works.

This repo is the source of truth for org-wide lint scripts, general coding standards, and shared testing principles. App repos and bootstrap templates consume the published npm package — they must not copy the scripts or docs into their own trees.

Do not open pull requests against other repos from work in this repo.

What lives here

  • scripts/ — eight shared lint checks, lint-drift orchestrator, and lint-staged-utils.mjs with Vitest allow/deny tests
  • eslint/ — recommended ESLint flat config for Easy rules
  • CODING_STANDARDS.md — pruned general coding standards for the org
  • docs/agents/testing-principles.md — shared testing principles for the org
  • docs/agents/issue-tracker.md — GitHub Issues ops and three-axis model
  • docs/agents/label-flow.md — stage:* lane sequence
  • docs/agents/triage-labels.md — attention flags, closing, flake ledger
  • .cursor/skills/issue-integration — land named issues with review loops
  • AGENTS.md — short agent entry point
  • CHANGELOG.md — Keep a Changelog history for published package versions

Pre-commit hook (this repo)

Same enforcement model as app repos: ESLint on staged files, then typecheck and test. Run pnpm run lint:drift periodically for the full CLI proof suite.

pnpm exec lint-staged
pnpm run typecheck
pnpm run test

Local development

pnpm install
pnpm test
pnpm run lint:drift   # full CLI proof suite (--tree); app repos run this periodically

pnpm run prepare installs Husky hooks when this checkout is the git toplevel.

Publishing to npm

Package name: @stryder-works/coding-standards (public scoped package).

CI stages the package from the release branch when the package version is not yet on npm and CHANGELOG.md has a heading for that version. The workflow is .github/workflows/publish.yml. It authenticates with npm Trusted Publishing (OIDC). It does not use a long-lived NPM_TOKEN. The publish step runs npm stage publish. A maintainer then approves the staged package.

Release branch

Use the release branch for version and publish work. Do not bump package.json version on main. The workflow file must exist on release.

Before each release, update release from main:

git checkout release
git merge main

Bump the version on release (npm version patch or npm version minor, or edit package.json). Add a Keep a Changelog section for that version in CHANGELOG.md in the same change. Use patch for backward-compatible fixes. Use minor for new exports, new presets, or stricter changes to the shared ./eslint preset. publishConfig.access is already set to public.

Push the version commit to release. The workflow then runs pnpm test and npm stage publish when npm does not have that version.

The workflow does not require a version change vs the previous commit. It stages when npm view reports a clear miss for the current version. After that version is live on npm, later pushes skip. They do not stage again.

If this commit changes package.json version and npm already has that version, the job fails.

If CHANGELOG.md has no ## [x.y.z] heading for the current version, the job fails and does not stage. pnpm test fails for the same absent heading before you push.

After a maintainer approves the staged package, merge release back to main. Push the version commit and tag:

git checkout main
git merge release
git push && git push --tags

One-time npm Trusted Publisher (Justin)

Do this once on npmjs.com before the first CI stage. The workflow cannot authenticate until this exists.

  1. Open package settings for @stryder-works/coding-standards.
  2. Add a GitHub Actions trusted publisher.
  3. Set organization or user to stryder-works.
  4. Set repository to coding-standards (GitHub repo Stryder-Works/coding-standards).
  5. Set workflow filename to publish.yml (filename only, with extension).
  6. Leave allowed actions at npm stage publish. New publishers use that default. Do not add npm publish.

Leave the GitHub environment name empty. This workflow does not use an environment.

Docs: Trusted publishing

Approve a staged package

CI does not make the version live. After the workflow stages the package, a maintainer approves it on npmjs.com under Staged Packages, or with:

npm stage list
npm stage approve <stage-id>

Approval requires 2FA. Inspect a staged tarball before you approve:

npm stage view <stage-id>
npm stage download <stage-id>

Requires npm CLI 11.15.0+ and Node 22.14.0+ for npm stage.

Docs: Staged publishing

Local dry-run

From a clean checkout on release:

pnpm test
npm publish --dry-run

Do not run npm publish or npm stage publish from a laptop for a normal release. CI stages from release.

You can run the workflow by hand with workflow_dispatch. A dry run still obeys the publish gate for a real stage.

Published package: https://www.npmjs.com/package/@stryder-works/coding-standards

License

This package uses the MIT license. Copyright (c) 2026 Justin Elias. Read LICENSE.

Consumption in app repos

Every app that pulls this package must follow this pattern. Do not copy scripts or docs from this repo into the app tree.

Declare in devDependencies

Add @stryder-works/coding-standards under devDependencies:

"devDependencies": {
  "@stryder-works/coding-standards": "^0.3.0"
}

pnpm:

pnpm add -D @stryder-works/coding-standards

npm:

npm install --save-dev @stryder-works/coding-standards

Bootstrap templates should wire this dependency, the shared ESLint config, and the enforcement model below for every new repo.

Enforcement model

App repos use two tiers:

Pre-commit (daily) — run the shared ESLint presets through lint-staged for fast feedback on staged files. Do not run all eight CLI bins on every commit.

Drift audit (periodic) — run the full CLI proof suite against the worktree to catch ESLint gaps, legacy violations, and standards drift. Treat this like architecture reviews or periodic useEffect audits: weekly, before major releases, or when onboarding a repo.

pnpm exec lint-drift

lint-drift runs all eight lint-* bins in --tree mode (full tracked worktree scan). lint-comments and lint-local-vi-mock are CLI-only (no ESLint rule). Folded rules use ESLint day-to-day; drift catches remaining gaps documented in the tradeoff sections below (for example barrel own-repo re-exports and describe ↔ test.describe nesting).

Deploy install (Vercel)

Some app repos skip dev dependencies on Vercel to speed deploys that do not run lint (for example pnpm install --frozen-lockfile --prod, or --no-optional when optional deps are also unused). That is an app-level build choice. It is not required for @stryder-works/coding-standards — the package is on public npm and installs with a normal pnpm install.

Cloud agents (Cursor)

The package is on the public npm registry, so a normal pnpm install installs it in Cloud Agent VMs. No git clone token or extra repo access is required.

If pre-commit runs ESLint via lint-staged, fail the install hook when the package did not install (for example test that node_modules/@stryder-works/coding-standards/package.json or node_modules/.bin/lint-drift exists — do not use pnpm exec lint-drift --help; the lint scripts exit non-zero for --help even when installed).

Local install

A normal local pnpm install or npm install installs dev dependencies, so pre-commit hooks keep working.

App config (.codingstandardsrc)

Add a JSON file at the app repo root to skip paths from the shared CLI lint scripts (lint-comments, lint-empty-catch, and the other six bins). ESLint ignores stay in the app eslint.config (see below).

{
  "ignore": ["legacy/**", "vendor/**", "generated/**"]
}

Patterns are minimatch globs relative to the repo root. Omit ignore or use an empty array when every tracked path should stay in scope.

The file is optional. Missing file means no extra ignores.

Shared ESLint config

Use this config in app pre-commit via lint-staged. Run pnpm exec lint-drift on a schedule for the full CLI proof suite.

This package exports a recommended ESLint flat config:

@stryder-works/coding-standards/eslint

The base export spreads @eslint/js recommended, so apps do not re-declare those core rules.

Install these peer dependencies in the app repo:

| Peer | Version range | Role | | --- | --- | --- | | @eslint/js | ^9.0.0 \|\| ^10.0.0 | Core recommended rules folded into the base export | | eslint | ^9.0.0 \|\| ^10.0.0 | Core linter | | typescript-eslint | ^8.0.0 | TypeScript parser and type-assertion rule | | @vitest/eslint-plugin | ^1.0.0 | Vitest rules (no-focused-tests, no-hooks, max-nested-describe) | | eslint-plugin-react-hooks (optional) | ^6.1.0 \|\| ^7.0.0 | React Hooks rules (React preset) | | eslint-plugin-jsx-a11y (optional) | ^6.10.0 | JSX accessibility rules (React preset) | | eslint-plugin-boundaries (optional) | ^5.0.0 | App-owned element graphs and boundaries/* rules |

Install eslint, @eslint/js, typescript-eslint, and @vitest/eslint-plugin with this package. Install eslint-plugin-react-hooks and eslint-plugin-jsx-a11y only when the app uses the React preset. Install eslint-plugin-boundaries only when the app uses boundary lint.

Compose the shared config into the app eslint.config:

import codingStandards from "@stryder-works/coding-standards/eslint";

export default [...codingStandards];

Add app-local configs after the spread when you need overrides.

Type-checked preset (opt-in)

For type-aware rules, spread the optional preset after the base config:

@stryder-works/coding-standards/eslint/type-checked
import codingStandards from "@stryder-works/coding-standards/eslint";
import typeChecked from "@stryder-works/coding-standards/eslint/type-checked";

export default [
  ...codingStandards,
  ...typeChecked,
  {
    languageOptions: {
      parserOptions: {
        projectService: true,
      },
    },
  },
];

The app must supply type information (projectService or project plus tsconfigRootDir). The preset spreads typescript-eslint recommendedTypeChecked, sets @typescript-eslint/no-deprecated to error, and ignores unused names that start with _.

Empty catch (no-empty)

The base export includes @eslint/js recommended, which sets core no-empty to error. That covers empty catch blocks for ESLint consumers.

Tradeoff versus scripts/lint-empty-catch.mjs:

  • Broader: no-empty also flags empty if, while, switch, try, and finally blocks.
  • Miss: a catch that holds only a comment passes no-empty. The CLI still flags that catch (statements.length === 0).

Prefer a miss over a false positive. pnpm exec lint-drift catches gaps ESLint misses.

Type assertions (consistent-type-assertions)

The shared config sets @typescript-eslint/consistent-type-assertions to error with assertionStyle: "never". That bans as and angle-bracket assertions. It still allows as const.

Tradeoff versus scripts/lint-as-assertions.mjs:

  • Match: as T and <T>value in .ts files fail. as const passes.
  • Match: real JSX in a .tsx file is not an assertion.
  • Match: files named *.gen.ts (and the other *.gen.* TypeScript extensions) stay out of this rule, like the CLI name skip.
  • Miss: a file that has only a generated-marker comment (and no .gen. name) still receives the ESLint rule. The CLI skips that file.
  • Miss: <T>value in a .tsx file is a parse error under the TypeScript JSX parse, not an assertion finding. The CLI also skips that form.

Prefer a miss over a false positive. pnpm exec lint-drift catches gaps ESLint misses.

Return types (explicit-function-return-type)

The shared config sets @typescript-eslint/explicit-function-return-type to error with allowExpressions, allowTypedFunctionExpressions, and allowHigherOrderFunctions enabled. That requires an explicit return type on top-level function declarations while still allowing typed arrow exports, typed function expressions, and higher-order callbacks to stay inferred.

Tradeoff versus CODING_STANDARDS.md alone:

  • Match: export function foo() { … } without a return type fails.
  • Match: export function foo(): T { … } and annotated module exports pass.
  • Match: arrow exports with an explicit return type or a typed const annotation, typed function expressions, and higher-order wrappers pass under the allow
  • Match: files named *.gen.ts (and the other *.gen.* TypeScript extensions) stay out of this rule, like the type-assertion block.
  • Miss: the rule runs only on TypeScript file extensions. Plain .js / .mjs top-level functions are not checked.
  • Miss: untyped exported arrow functions (export const fn = () => …) still fail even with allowExpressions; annotate the return type or add a typed const annotation so allowTypedFunctionExpressions applies.

Framework-inferred returns (for example TanStack Router getRouter) stay documented in CODING_STANDARDS.md with an inline eslint-disable-next-line and a reason.

Prefer a miss over a false positive.

Focused tests (vitest/no-focused-tests)

The shared config sets vitest/no-focused-tests to error for test and spec files (*.{test,spec}.*).

Tradeoff versus scripts/lint-focused-tests.mjs:

  • Match: test.only, it.only, and describe.only fail.
  • Match: test.skip, it.skip, describe.skip, and plain test / it / describe pass.
  • Match: focused identifiers inside comments or strings do not fail.
  • Miss: suite.only, fit, and fdescribe pass under this rule. The CLI still flags those forms.
  • Miss: the rule runs only on test and spec file names. The CLI scans every parseable file.

Prefer a miss over a false positive. pnpm exec lint-drift catches gaps ESLint misses.

Test hooks (vitest/no-hooks)

The shared config sets vitest/no-hooks to error with beforeAll and afterAll allowed. That bans beforeEach and afterEach in test and spec files.

Tradeoff versus scripts/lint-before-each-after-each.mjs:

  • Match: beforeEach and afterEach fail in test files.
  • Match: beforeAll and afterAll pass.
  • Miss: the rule runs only on test and spec file names. The CLI scans every parseable file.

Prefer a miss over a false positive. pnpm exec lint-drift catches gaps ESLint misses.

Nested describe (vitest/max-nested-describe)

The shared config sets vitest/max-nested-describe to error with max: 1. That allows one top-level describe and one nested describe per test file.

Tradeoff versus scripts/lint-nested-describe.mjs:

  • Match: a third nested describe fails.
  • Miss: the rule runs only on test and spec file names. The CLI scans every parseable file.

Prefer a miss over a false positive. pnpm exec lint-drift catches gaps ESLint misses.

React preset (eslint/react)

React apps can add a second flat config export:

@stryder-works/coding-standards/eslint/react

Install eslint-plugin-react-hooks and eslint-plugin-jsx-a11y with this package when you use the React preset.

Compose the recommended and React presets in the app eslint.config:

import codingStandards from "@stryder-works/coding-standards/eslint";
import codingStandardsReact from "@stryder-works/coding-standards/eslint/react";

export default [...codingStandards, ...codingStandardsReact];

The React preset includes:

  • eslint-plugin-react-hooks flat recommended
  • eslint-plugin-jsx-a11y flat recommended
  • A no-restricted-syntax ban on "use no memo" and "use no forget" directives in .jsx and .tsx files (React Compiler opt-outs)
  • Re-declares module-import no-restricted-syntax bans on .tsx and barrel index.{ts,tsx} paths so those rules stay active after the React spread

Prefer a miss over a false positive for the compiler-opt-out ban: strings and comments that mention those directives do not fail. The ban does not run on plain .ts files.

[email protected] still declares an eslint peer through ^9 only. The plugin runs on ESLint 10. Until upstream widens that peer range, add a package-manager override in the app repo when you use ESLint 10:

"pnpm": {
  "peerDependencyRules": {
    "allowedVersions": {
      "eslint-plugin-jsx-a11y>eslint": "10"
    }
  }
}

Module imports (barrels)

The shared config bans export * from in TypeScript files and bans re-export barrels in index.{ts,tsx} files under common module roots (components, features, lib, config, modules). See CODING_STANDARDS.md module-imports.

Tradeoff versus scripts/lint-own-repo-barrels.mjs:

  • Match: export * from fails in any .ts, .tsx, .mts, or .cts file.
  • Match: export { x } from './y' fails in index.{ts,tsx} under the default module-root globs.
  • Match: a facade index.ts that exports local symbols or functions passes.
  • Miss: export { x } from outside index.{ts,tsx} passes under this rule. The CLI still flags own-repo package-name and import-map re-exports in any file.
  • Miss: index.{ts,tsx} outside the default module-root globs passes. Override the globs when your app uses different roots.

Prefer a miss over a false positive. pnpm exec lint-drift catches gaps ESLint misses.

Override barrel index globs by importing the modules factory:

import codingStandards from "@stryder-works/coding-standards/eslint";
import { createModulesConfig } from "@stryder-works/coding-standards/eslint/modules";

export default [
  ...codingStandards,
  ...createModulesConfig({
    barrelIndexFiles: [
      "**/widgets/**/index.{ts,tsx}",
      "**/components/**/index.{ts,tsx}",
    ],
  }),
];

The factory export is also available without the full recommended spread:

@stryder-works/coding-standards/eslint/modules

Boundaries (eslint-plugin-boundaries)

eslint-plugin-boundaries is an optional app peer. This package does not ship a default element graph or boundary rules.

Each app owns its elements map, dependency policies, and boundaries/* rules in the app eslint.config. One app may use feature and module elements. Another app may use membership and Square module elements.

Do not add shared boundary rules here that assume a folder layout.

Pre-commit hook

In the app repo's .husky/pre-commit (edit the app repo yourself — do not open PRs from this repo), run ESLint on staged files via lint-staged. Compose the shared config from this package in the app's lint-staged config (or eslint.config).

pnpm exec lint-staged

Add the app repo's own typecheck and test after that line.

Drift audit

Run the full CLI proof suite on a schedule (see Enforcement model above):

pnpm exec lint-drift

Or invoke individual bins in --tree mode when debugging one rule:

pnpm exec lint-comments --tree
pnpm exec lint-empty-catch --tree

Staged-mode CLI bins (default, no --tree) remain available for this repo's own hook and for custom workflows.

Point the app repo's AGENTS.md at the installed docs (do not copy them):

  • node_modules/@stryder-works/coding-standards/CODING_STANDARDS.md
  • node_modules/@stryder-works/coding-standards/docs/agents/testing-principles.md

Or use the GitHub URLs:

  • https://github.com/Stryder-Works/coding-standards/blob/main/CODING_STANDARDS.md
  • https://github.com/Stryder-Works/coding-standards/blob/main/docs/agents/testing-principles.md

Project-specific standards (domain context, trade dress, forge workflow) stay in each app repo.