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

@avi2dg/checks

v0.42.0

Published

Deterministic checks shared across a set of TypeScript repositories

Readme

checks

@avi2dg/checks is the kit of deterministic checks a TypeScript repository installs to hold its code, tests, commits, CI wiring and docs to one shared standard. It ships the lint gates checks-lint runs over each pull request, the test runners, and a defineConfig for oxlint, Knip and dependency-cruiser. It also ships the configs a repository extends for tsc, commitlint, bun and Stryker. Each repository owns its workflows and native tool configs, as Native settings maps.

Before you begin

  • A git repository, whose history the range gates read.
  • Bun 1.4.3, which runs every bin.
  • The peer dependencies, at the exact versions the kit pins:
    • @effect/tsgo 0.45.0
    • @swc/core 1.16.2
    • dependency-cruiser 18.4.0
    • effect 4.0.0
    • jscpd 5.3.2
    • oxlint 1.83.0
    • oxlint-tsgolint 7.0.2002
    • typescript 7.0.2
  • The optional peers, which only an opt-in check loads, at the exact versions the kit pins:
    • @axe-core/playwright 4.13.0
    • html-validate 11.16.0
    • playwright-core 1.63.0
    • postcss-html 2.0.0
    • stylelint 17.16.0

Install

To consume the kit from a repository:

  1. Add the kit and its peers:

    bun add -d @avi2dg/checks @effect/[email protected] @swc/[email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected]
  2. Write oxlint.config.ts with the kit's builder, saying whether the sources are Effect programs:

    import { defineConfig } from "@avi2dg/checks/oxlint";
    
    export default defineConfig({ effect: true });
  3. Keep oxlint out of node_modules/ through .gitignore:

    node_modules/
  4. Extend the tsconfig fragment in tsconfig.json:

    {
      "extends": "@avi2dg/checks/tsconfig.effect.json"
    }
  5. Copy the bunfig preset:

    cp node_modules/@avi2dg/checks/bunfig.toml bunfig.toml
  6. Name the files nothing imports in knip.config.ts:

    import { defineConfig } from "@avi2dg/checks/knip";
    
    export default defineConfig({ entry: ["src/index.ts"] });
  7. Write dependency-cruiser.config.ts only when the kit's import rules need an entry point or a boundary of the repository's own:

    import { defineConfig } from "@avi2dg/checks/dependency-cruiser";
    
    export default defineConfig({ orphans: ["^src/bin[.]ts$"] });
  8. Add scripts to package.json, replacing the build entry with the repository's own build command:

    "build": "bun build src/index.ts --outdir dist --target node && checks-effect-scope",
    "lint": "oxlint && checks-lint",
    "typecheck": "tsc --noEmit && effect-tsgo diagnostics --project tsconfig.json --format text --strict",
    "test": "checks-test"
  9. Write the Bun version Before you begin names to .bun-version, which checks-ci-wiring holds every setup-bun step to.

  10. Run the scripts on every pull request in .github/workflows/ci.yml, fetching the whole history the range needs:

    on:
      pull_request:
    jobs:
      checks:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v5
            with:
              fetch-depth: 0
          - uses: oven-sh/setup-bun@v2
            with:
              bun-version-file: .bun-version
          - run: bun install --frozen-lockfile
          - run: bun run build
          - run: git diff --exit-code
          - run: bun run lint
          - run: bun run typecheck
          - run: bun run test

Lint the pull request title in the same job with one step:

      - id: title
        name: lint the title
        env:
          PR_TITLE: ${{ github.event.pull_request.title }}
          GH_TOKEN: ${{ github.token }}
        run: bunx checks-commit-title

A repository whose branch protection requires commitlint keeps that required status name while commitlint.yml goes away. The same job reports the title step's outcome under that name on every run, which needs statuses: write:

      - name: report the title as commitlint
        if: always()
        env:
          GH_TOKEN: ${{ github.token }}
          HEAD_SHA: ${{ github.event.pull_request.head.sha }}
          OUTCOME: ${{ steps.title.outcome }}
        run: |
          state=failure
          if [ "$OUTCOME" = success ]; then state=success; fi
          gh api "repos/$GITHUB_REPOSITORY/statuses/${HEAD_SHA:-$GITHUB_SHA}" -f state="$state" -f context=commitlint -f target_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" --silent

A private repository sets runs-on: ${{ vars.CI_RUNS_ON || 'ubuntu-latest' }} on each job, as checks-ci-wiring requires. checks-effect-scope writes the Effect paths of oxlint.config.ts and the kit's severities into tsconfig.json, as The Effect rules says. bun run lint then ends with checks-lint: <count> gate(s) pass.

What runs

checks-lint runs each of these gates that applies to the repository, and names every one that fails. A gate reads either the working tree or the range checks-lint resolves. The table groups the gates by vector, the part of a repository each one judges.

| Vector | Gate | Reads | Runs in | | --- | --- | --- | --- | | complexity | checks-suppressions-ratchet | the range | every repository | | complexity | checks-repetition | the range | a repository tracking *.ts or *.tsx | | complexity | checks-unused | the working tree | a repository tracking *.ts or *.tsx or *.astro | | complexity | checks-exports | the range | a repository tracking *.ts or *.tsx | | quality | checks-lint-coverage | the working tree | a repository tracking *.ts or *.tsx or *.astro | | quality | checks-comment-gate | the range | every repository | | quality | checks-effect-scope | the working tree | a repository tracking oxlint.config.ts | | quality | checks-frontend-syntax | the working tree | a repository tracking frontend-syntax.json | | testing | checks-test-layout | the working tree | a repository tracking *.ts or *.tsx | | testing | checks-quarantine-clock | the range | every repository | | docs | checks-docs | the range, and every agent file at the head commit | every repository | | delivery | checks-commit-identity | the range | every repository | | delivery | checks-ci-wiring | the working tree | every repository | | delivery | checks-secrets | the range | every repository | | dependencies | checks-imports | the working tree | a repository tracking *.ts or *.tsx | | dependencies | checks-advisories | the range | a repository tracking bun.lock |

These bins run on their own:

  • checks-test runs the suite as scripts.test and refuses a skip without a reason at its test site.
  • checks-flake runs the suite on a schedule and records the seeds a flaky test fails with.
  • checks-mutation runs Stryker for scoped checks and refuses a full run outside CI.
  • checks-mutation-compare compares the mutants of two reports and lists each one that regresses.
  • checks-mutation-baseline restores the newest mutation baseline from main, saves it on a self-hosted runner's disk in place of an artifact, and deletes superseded baselines after a main run.
  • checks-subsumed-tests lists each test another test subsumes in a mutation run.
  • checks-changelog writes the pending release into CHANGELOG.md from the conventional commits since the last release.
  • checks-release-notes writes one CHANGELOG.md section to a file for a GitHub release.
  • checks-release-report tells whether the history holds unreleased features or fixes since the last tag.
  • checks-release-pr opens or refreshes the pull request that releases the next version, and dispatches its checks.
  • checks-release-tag tags a landed release commit with its version and dispatches the release workflow on the tag.
  • checks-vendor pins each library its prepare arguments name to a shared read-only clone and links it under repos/.
  • checks-browser opens a product's built pages in Chrome and fails on the layout, keyboard, motion, accessibility, nesting and asset checks its browser-checks.json declares.
  • checks-commit-title lints the pull request title in one step of the ci job.
  • checks-docs-only tells whether a change touches only top-level Markdown and Markdown under docs/, so a docs-only change skips the full run.

checks-lint has its own page, which says which range it resolves. oxlint runs through its own tool, as the pages under Related topics say.

Upgrade

To move a repository to a newer release of the kit:

  1. Run the install line again, which moves the kit to its newest release and the peers to the versions it pins. A repository that opted in to checks-browser or checks-frontend-syntax also reruns the bun add line on its page.
  2. Run bun run build, whose checks-effect-scope rewrites the Effect override and the kit's severities in tsconfig.json when a release changes them. A severity key the release drops stays in tsconfig.json until the repository removes it.
  3. Copy node_modules/@avi2dg/checks/bunfig.toml over bunfig.toml again, since checks-test-layout compares the copy with the installed preset.
  4. Run bun run lint, bun run typecheck and bun run test.

The repository's lockfile pins the kit, so a repository moves only when it runs these steps. CHANGELOG.md, shipped in the package, lists what each release changed.

Where things are

Every path is relative to the installed package, node_modules/@avi2dg/checks/.

| Path | What it holds | | --- | --- | | CHANGELOG.md | every release, and what it changed | | docs/ | a reference page per bin and per shared config, and why the kit is shaped this way | | bunfig.toml | the bunfig preset a repository copies | | commitlint.config.js | the shared commitlint config | | dependency-cruiser.config.js | the kit's dependency-cruiser rules as a base a .dependency-cruiser.cjs extends by path, which the build writes | | knip-base.json | the Knip include setting, for a configuration that spreads it | | src/ | every bin, which a package script calls by its checks- name, the modules the bins import, and the Effect language service severities under src/quality/presets/ | | dist/ | the compiled oxlint plugins, the config builders @avi2dg/checks/oxlint, @avi2dg/checks/knip and @avi2dg/checks/dependency-cruiser resolve to, and the doc templates, one template per kind of doc file | | oxlintrc.json | the oxlint base as a config a .oxlintrc.json extends by path, which the build writes | | stryker.preset.js | the Stryker mutation-testing preset, which refuses a full run outside CI | | tsconfig.effect.json | the tsconfig fragment with the shared compiler options and the Effect language-service block | | ts-reset.d.ts | the two ts-reset rules tsconfig.effect.json lists in files |

Related topics