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

dagward

v0.2.0

Published

Deterministic architecture review for TypeScript projects: dependency graphs at folder, file, and function level.

Downloads

42

Readme

Dagward

Deterministic architecture enforcement for the age of AI coding agents.

Your dependency graph should be a DAG. Dagward keeps it one — even when AI agents write the code.

AI agents write undisciplined code that compounds: more abstractions, more context, slower every session. Dagward enforces your rules deterministically and flips the compounding: cleaner structure, smaller context, faster and cheaper every session.

Dagward turns your architecture into something machines must obey:

  • Infer — Scan your repo, get a draft of your actual module boundaries and dependency rules. Confirm instead of writing from scratch.
  • Enforce — Every change is checked against the rules: as a Claude Code hook, pre-commit, and in CI. Checks are deterministic graph queries — no AI judging AI.
  • Feed back — Violations return structured feedback the agent can act on: which rule, why it exists, how to fix. Agents correct themselves; humans stay out of the loop.
  • Exempt with intent — Real architectures have exceptions. Annotated exemptions are versioned in git and become your team's architecture decision record.

AI proposes rules. Humans approve them. Machines enforce them. No line of code's compliance depends on a model's mood.


Quickstart

# 1. Infer your architecture (read-only, ~1 min on most repos)
npx dagward init

# 2. Review the draft — edit dagward.yml, then commit it
git add dagward.yml && git commit -m "chore: adopt architecture rules"

# 3. Check the whole repo
npx dagward check

# 4. Wire it into Claude Code (one command)
npx dagward install-hook claude-code

That's it. From now on, every edit an agent makes is checked against your rules the moment it lands — and violations are fed back to the agent in a format it can act on.

Requirements: Node.js ≥ 20, a TypeScript project with a tsconfig.json. Monorepos (npm/pnpm/yarn workspaces) are supported.

What init produces

dagward init builds the full dependency graph using the TypeScript compiler API (real module resolution — paths, workspace deps, conditional exports), detects strongly connected components and layer structure, and writes two files:

  • ARCHITECTURE.md — a human-readable snapshot of your system as it actually is: layers, module boundaries, existing cycles, and the edges that look accidental. Useful on its own, even if you never adopt the rules.
  • dagward.yml — a draft rule file. Nothing is enforced until you review, edit, and commit it. Confirming is a 10-minute job; writing from scratch would take days.

Visualize

npx dagward init && npx dagward viz

dagward viz renders the graphs in dagward-out/ to a single self-contained viz.html — no network, no CDN, works offline — and opens it in your default browser (--no-open to skip). Tabs switch between folder, file, and function level; dependencies point downward, type-only imports are dashed, and cycle members are flagged red.

The rule file

Rules are declarative YAML — language-agnostic by design, and readable by both humans and agents. MVP supports three rule types:

version: 1

layers:                      # topological order: earlier may not depend on later
  - name: domain
    match: "packages/domain/**"
  - name: application
    match: "packages/app/**"
  - name: infrastructure
    match: "packages/infra/**"

rules:
  - id: no-cycles
    type: no-cycles
    level: package           # package | file
    rationale: >
      Cycles between packages cause initialization-order bugs and make
      modules impossible to extract or test in isolation.

  - id: layering
    type: layer-order        # enforces the `layers` list above
    ignore-type-imports: true
    rationale: >
      Domain logic must stay framework-free. Dependencies point inward.

  - id: no-direct-db-from-api
    type: forbidden-edge
    from: "packages/api/**"
    to: "packages/infra/db/**"
    rationale: >
      API handlers go through the repository layer (ADR-012, 2024-06).
      Direct DB access bypassed row-level security once. Never again.

rationale is not a comment — it is part of the enforcement. When an agent violates a rule, the rationale is included in the feedback, so the agent understands why and fixes the code instead of fighting the rule.

Type-only imports (import type) are tracked as a separate edge kind and can be exempted per rule — a type-level cycle is not a runtime cycle, and Dagward knows the difference.

Checking

dagward check                 # full repo
dagward check --changed       # only files changed since HEAD (fast path for hooks)
dagward check --format agent  # structured JSON for agent consumption

Checks are pure graph queries — cycle detection via strongly connected components, layer rules as reachability queries on the condensation. Deterministic, reproducible, milliseconds on the incremental path. No network calls, no LLM, no flakiness.

Exit code 0 = clean, 1 = violations, 2 = config error. That's your CI gate:

# .github/workflows/architecture.yml
- run: npx dagward check --format github

Agent feedback

With --format agent, a violation looks like this:

{
  "violations": [{
    "rule": "no-direct-db-from-api",
    "severity": "error",
    "edge": {
      "from": "packages/api/src/checkout.ts",
      "to": "packages/infra/db/client.ts",
      "kind": "value-import"
    },
    "rationale": "API handlers go through the repository layer (ADR-012, 2024-06). Direct DB access bypassed row-level security once. Never again.",
    "fix_direction": "Import from packages/app/repositories instead, or add a repository method if none fits.",
    "exemption_hint": "If this dependency is intentional, add an annotated exemption — see docs/exemptions.md."
  }]
}

The Claude Code hook feeds this back automatically after each edit. In practice, agents fix their own violations on the next turn without human intervention.

Annotations

Graph nodes can carry an optional annotation object — summary, inputs, outputs, should, shouldNot, side (frontend/backend/shared/tooling), pure — written by a human or an AI pass, never by dagward itself. Dagward preserves annotations by node id when regenerating graphs, so dagward init can run on every change without losing them. Enforcement remains purely deterministic; annotations are context for humans and agents reading the graph.

Exemptions

Real architectures have exceptions. Unexplained exceptions are how architectures rot — so every exemption requires a reason, and lives in git:

exemptions:
  - rule: layering
    from: "packages/domain/src/legacy/pricing.ts"
    to: "packages/infra/feature-flags/**"
    reason: "Pre-dates the flag abstraction. Tracked in TICKET-4102."
    added-by: "@yourname"
    added: 2026-07-19

Over time, your exemption log becomes something no wiki ever stays: an accurate, versioned record of every architectural decision and its debt.

What Dagward is not

  • Not a linter. Linters check code style within a file. Dagward checks the structure between files — the part no single diff reveals and no agent context window retains.
  • Not an AI reviewer. Review bots use an LLM to judge LLM output — probabilistic opinions about probabilistic code. Dagward's enforcement is a graph query. Same input, same answer, every time.
  • Not a replacement for CI, tests, or review. It is one more deterministic gate — the one specifically shaped for the failure mode AI agents actually have.

Roadmap

  • v0.2 — MCP server: read-only architecture tools (check_change, query_dependencies, explain_rule) so agents can consult the rules before writing code, and interactive rule inference inside your agent session.
  • v0.3 — Cursor hook, watch mode, richer rule types (public-API surfaces, tag-based boundaries).
  • Later: Python analyzer (same rule format, pluggable analyzer), team features (exemption approval flow, drift trends).

Multi-language support is a design constraint from day one: the rule format and engine are language-agnostic; only the analyzer is TypeScript-specific.

Status

Early. Dagward currently guards its own repository and a handful of production monorepos. Expect sharp edges; expect fast fixes. Issues and violation war stories are equally welcome.

License

Apache-2.0. The Dagward name and logo are trademarks of the project and are not covered by the code license.