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

@coryrylan/tools

v1.1.0

Published

Shared ESLint, Prettier, Stylelint, Vale, Vite, and Vitest configs, custom lint rules, and pi coding-agent extensions - for keeping codebases maintainable when coding agents are the primary contributors.

Readme

@coryrylan/tools

Shared tooling configs - ESLint, Prettier, Stylelint, Vale, Vite, and Vitest - plus custom ESLint rules for keeping codebases maintainable when coding agents are the primary contributors.

Philosophy

When an agent is the one writing most of a diff, prose instructions living in an AGENTS.md file are advisory at best. They have to be loaded into context, correctly interpreted, and remembered turns later, and none of that is guaranteed on any given run. Prose decays: it drifts out of context, gets skimmed instead of read, or is outweighed by whatever the agent is focused on in the moment. A lint rule has none of these failure modes: it runs on every diff, every time, and fails the build instead of hoping to be noticed. Every rule and every shared config in this package exists to replace a paragraph an agent would otherwise have to read (and might ignore, forget, or misapply) with a deterministic check or preset that gates the diff instead.

Surfaces

| Entry | What it ships | | ------------------------------------------------ | -------------------------------------------------------------------------------- | | @coryrylan/tools/eslint | Flat configs plus the custom tools/* rule plugin. | | @coryrylan/tools/prettier | The shared Prettier config. | | @coryrylan/tools/stylelint | Shared Stylelint config (standard + logical properties + design-token checks). | | @coryrylan/tools/vite | createNodeLibraryBuildConfig / createBrowserLibraryBuildConfig factories. | | @coryrylan/tools/vite/plugins/write-if-changed | Vite plugin that skips writing chunks whose content didn't change. | | @coryrylan/tools/vite/plugins/dts | Vite plugin that runs the consumer's TypeScript compiler for declaration output. | | @coryrylan/tools/vitest | nodeTestConfig preset for node-environment unit tests. | | @coryrylan/tools/vitest/browser | browserTestConfig preset for browser-mode (Playwright Chromium) tests. | | dist/vale/ | Vale starter kit: ini template plus shared accept/reject vocabulary. | | @coryrylan/tools/pi/greeting | Pi extension - speaks a greeting via macOS say on session start. | | @coryrylan/tools/pi/audio-summary | Pi extension - speaks a short summary of each agent turn. | | @coryrylan/tools/pi/hooks | Pi extension - Claude-Code-style lifecycle hooks from .agents/hooks.json. |

ESLint

pnpm add -D eslint @coryrylan/tools typescript typescript-eslint

The remaining peers (@eslint/js, @eslint/json, eslint-plugin-jsdoc) install automatically as regular peer dependencies under pnpm 10 or npm. Yarn users should add them to devDependencies explicitly.

// eslint.config.js
import { typescriptConfig, jsonConfig } from '@coryrylan/tools/eslint';

export default [...typescriptConfig, ...jsonConfig];

A default export is also available if you'd rather reach into the plugin and config map directly: import agentLintRules from '@coryrylan/tools/eslint' exposes { plugin, configs }, where configs is keyed by typescript, tests, browser, html, and json.

Configs

| Config | What it enables | Requirements | | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | | typescriptConfig | On all JS/TS files: size/complexity budgets (complexity 8, max-depth 3, max-params 3, max-lines 500, max-statements 15, max-lines-per-function 50, max-nested-callbacks 3) plus eqeqeq, prefer-const, no-shadow, no-warning-comments, no-param-reassign, and friends, and 5 syntax-only tools/* rules. On TS files: type-aware strictTypeChecked, plus @typescript-eslint/no-floating-promises, only-throw-error, consistent-type-imports, switch-exhaustiveness-check, explicit-member-accessibility (no-public), a #private-over-private selector, no-explicit-any, no-unnecessary-boolean-literal-compare, jsdoc checks (informative-docs, no-types, valid-types, check-tag-names), and the type-aware tools/no-deep-class-inheritance rule. The default starting point for a new agent-maintained project - relax specific rules per-project rather than swapping this config out. | typescript-eslint, eslint-plugin-jsdoc, typescript >=5.5.0 <6.1.0, parserOptions.projectService | | testsConfig | Relaxes size/complexity budgets (max-lines, max-lines-per-function, max-statements, max-nested-callbacks, unused-expression checks) for *.test.* / *.spec.* files. | combine with another config | | browserConfig | globalThis-over-window/document/location restrictions, plus 3 cleanup rules (require-listener-cleanup, require-observer-cleanup, require-timer-cleanup). | none extra | | htmlConfig | @html-eslint recommended structural rules for *.html files (duplicate ids/attrs, obsolete tags, lang/alt requirements, baseline feature checks), with pure-formatting rules off in favor of Prettier and frontmatter-aware parsing for static-site templates. | @html-eslint/eslint-plugin, @html-eslint/parser | | jsonConfig | @eslint/json structural rules for *.json (JSONC variant for tsconfig*.json), plus no-unpinned-dependency-ranges scoped to package.json. | @eslint/json |

Rules

| Rule | What it catches | Enabled by | | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------ | | tools/no-dead-code | Disallow commented-out source code left behind in comments. | typescript | | tools/no-deep-class-inheritance | Disallow class inheritance chains deeper than a configured maximum. | typescript | | tools/no-single-consumer-abstraction | Disallow exported abstractions (base classes) with fewer than two implementation consumers. | typescript | | tools/no-unjustified-disable | Require every eslint-disable* directive to carry a reason (and, by default, an explicit rule list). | typescript | | tools/no-reexport-barrels | Flag files that re-export from more than a configured number of modules. | typescript | | tools/consistent-error-messages | Require thrown/constructed Errors to carry a non-empty, informative message. | typescript | | tools/require-listener-cleanup | Require a matching removeEventListener for every addEventListener added in a setup lifecycle method; forbid addEventListener in the constructor. | browser | | tools/require-observer-cleanup | Flag ResizeObserver/MutationObserver/IntersectionObserver/PerformanceObserver instances created without storing a reference. | browser | | tools/require-timer-cleanup | Flag setInterval handles that are never stored or never cleared. | browser | | tools/no-unpinned-dependency-ranges | Require package.json dependency version specifiers appropriate to the package's publish status and dependency kind. | json |

Prettier

pnpm add -D @coryrylan/tools prettier

Reference the config straight from package.json:

{ "prettier": "@coryrylan/tools/prettier" }

Or import and spread it in a prettier.config.js to override options. Embedded template literals stay hand-formatted (embeddedLanguageFormatting: 'off'). See src/prettier/docs.

Stylelint

pnpm add -D @coryrylan/tools stylelint stylelint-config-standard
// stylelint.config.js
export { default } from '@coryrylan/tools/stylelint';

Layers stylelint-config-standard with logical-property enforcement (no physical margin-*/padding-*) and design-token checks (no hardcoded pixel values in spacing properties). See src/stylelint/docs.

Vale

Install the Vale binary (mise use vale, or brew), then point a .vale.ini at the styles this package ships:

StylesPath = node_modules/@coryrylan/tools/dist/vale/styles
Vocab = Tools
Packages = Google, write-good

Run vale sync once to download the style packages. The full template with per-filetype sections lives at src/vale/vale.ini. See src/vale/docs.

Vite

pnpm add -D @coryrylan/tools vite
// vite.config.ts
import { defineConfig, mergeConfig } from 'vite';
import { createNodeLibraryBuildConfig } from '@coryrylan/tools/vite';

export default defineConfig(mergeConfig(createNodeLibraryBuildConfig({ entry: { index: 'src/index.ts' } }), {}));

ESM-only, every bare specifier externalized, preserveModules for deep imports, no minification. The write-if-changed and dts plugins ship as deep imports under @coryrylan/tools/vite/plugins/. See src/vite/docs.

Vitest

pnpm add -D @coryrylan/tools vitest
// vitest.config.ts
import { defineConfig } from 'vitest/config';
import { nodeTestConfig } from '@coryrylan/tools/vitest';

export default defineConfig(nodeTestConfig);

@coryrylan/tools/vitest/browser exports browserTestConfig for real-Chromium browser-mode tests (requires the optional @vitest/browser-playwright, @vitest/coverage-istanbul, and playwright peers) with istanbul coverage gated at 90% across lines, branches, functions, and statements. See src/vitest/docs.

Pi extensions

pi install npm:@coryrylan/tools

Three pi coding-agent extensions, shipped as a pi package (pi manifest key in package.json, pi-package keyword): greeting, audio-summary, and hooks. Pi provides @earendil-works/pi-ai/@earendil-works/pi-coding-agent/typebox at runtime, so there is nothing extra to install. See src/pi/docs.

Peer dependencies

Every peer beyond eslint is scoped to the surface that needs it; the non-ESLint peers are marked optional, so install them with the surface you use.

  • typescript must satisfy >=5.5.0 <6.1.0 for type-aware linting (typescriptConfig) - this is the range typescript-eslint supports; newer typescript majors are not yet compatible with type-aware rules here. Note that a bare pnpm add -D typescript resolves to 7.x (the native compiler, which no longer ships the JS compiler API typescript-eslint needs), so install an explicit typescript@6 until typescript-eslint supports 7.
  • typescript-eslint >=8.40.0 and eslint-plugin-jsdoc >=60.0.0 are only needed if you use typescriptConfig.
  • @eslint/json >=0.13.0 is only needed if you use jsonConfig.
  • @html-eslint/eslint-plugin >=0.61.0 and @html-eslint/parser >=0.61.0 are only needed if you use htmlConfig.
  • prettier >=3 for the Prettier config; stylelint >=17 and stylelint-config-standard >=40 for the Stylelint config.
  • vite >=8 for the Vite factories and plugins; vitest >=4 for the test presets, plus @vitest/browser-playwright >=4, @vitest/coverage-istanbul >=4, and playwright >=1.50 for browserTestConfig.
  • @earendil-works/pi-ai, @earendil-works/pi-coding-agent, and typebox for the pi extensions - the pi CLI provides all three at runtime, so they're optional peers with no version floor.

License

MIT - see LICENSE. Copyright (c) 2026 Cory Rylan.