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

@dowel/dowel

v0.3.1

Published

dowel — a compiled, opinionated architecture linter. TS-native rule authoring over a Rust engine (Project, AST, shadow-DB SQL oracle).

Downloads

1,374

Readme

dowel

A deterministic harness for coding agents. dowel compiles your architecture into rules and checks the whole codebase on every run, so an AI agent — or a human — gets the same non-negotiable feedback every time: what's allowed, what isn't, and why.

npm i -D @dowel/dowel && npx dowel setup

Why

Coding agents amplify whatever patterns already exist in a repo — including the uneven ones. Boundaries with exceptions get copied as exceptions; the codebase drifts. The usual answer is more prose — CLAUDE.md, AGENTS.md, .cursorrules — but prose is non-deterministic: the model may read it, may not, and it rots as the codebase grows.

"Agents write the code; linters write the law. Agents iterate against deterministic feedback far better than they iterate against vibes."

dowel moves the gate into the structure of the codebase. Architecture becomes compiled, checkable law:

  • Deterministic — the same diagnostics every run, not a suggestion the model weighs. Exit code is non-zero on any error, so it gates CI and agent loops.
  • Whole-codebase, every time — no context window to overflow, no AGENTS.md to keep in sync. The rules are the spec.
  • Diagnostics + intent — every finding states the rule's intent, so the agent reading it learns the pattern and fixes it, then carries the pattern forward. The codebase teaches the next agent.

What it checks that a type-checker can't

  • Architecture boundaries — vertical-slice structure, cross-slice imports, layer purity (no SQL in services, no Response in repos, Result at write boundaries), folder vocabulary, ownership.
  • Raw SQL against a real schema — dowel builds a shadow database from your migrations (Postgres or SQLite/D1) and PREPAREs every query against it, catching drift, missing indexes, and N+1s a type-checker never sees. If the shadow is unreachable it says so, loudly — never a silent pass.

Quickstart

npm i -D @dowel/dowel
npx dowel setup          # detects stack/DB/structure, picks a profile,
                         # writes arch-lint.toml, scaffolds rules/
npm run lint:arch        # or: npx dowel

dowel setup reads your repo and recommends a profile — a curated rule set for your stack:

| Profile | For | |---------|-----| | node-postgres | Node/Hono + Postgres | | cloudflare-d1 | Cloudflare Workers + D1 (SQLite) | | sanity-nextjs | Next.js + Sanity (no SQL) | | generic / portable | any TypeScript / any language baseline |

Authoring rules

Portable rules ship in the packs. Codebase-specific rules live with your codebase as TypeScript — type-checked by your own tsc, scaffolded by dowel new-rule:

// rules/no-sql-outside-repos.ts
import { defineRule } from "@dowel/dowel";

export default defineRule({
  id: "NO_SQL_OUTSIDE_REPOS",
  intent: "raw SQL lives only in repos/ — services compose, repos query",
  check(project, ctx) {
    return project.files()
      .filter((f) => /\bselect\b/i.test(f.text) && !f.relPath.includes("/repos/"))
      .map((f) => ({ severity: "error", file: f.path, line: 1,
                     message: "move SQL into a repo" }));
  },
});
dowel new-rule NO_SQL_OUTSIDE_REPOS   # scaffolds the rule + passing/violation fixtures

Every rule declares when it fires (scope — e.g. exempt tests), which variant (typed options), and is toggled per-repo in arch-lint.toml — so calibration is data, not a fork of the rule.

How it's built

The Rust engine ships as a prebuilt native Node addon: npm i pulls exactly one @dowel/dowel-<platform> package via optionalDependencies — no Rust toolchain, no post-install compile, no committed binary. Borrows hard-won patterns from ruff/oxc (speed), sqlc (DB-checked SQL), and Squawk (migration safety).

Platform support: darwin-arm64 ships today; the Linux/Windows binaries land via the CI build matrix. On an unsupported platform the loader tells you.

License

MIT OR Apache-2.0