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

crayon-c4

v0.2.0

Published

Generate a CRAYON-C4 architecture model (JSON) from a Next.js, React, .NET, or Java repository. Re-runnable, merge-safe, configurable via .crayon/config.json.

Downloads

50

Readme

crayon-c4

Generate a CRAYON-C4 architecture model from your code — then import it into the web app, where a non-destructive merge keeps your manual curation (descriptions, renames, colours, layout) while the diagram catches up to the latest code.

Use it

npx crayon-c4 .

Run it at your repo root. It detects the stack (Next.js / React / .NET / Java — Maven or Gradle), analyzes the code, and writes:

  • crayon-c4-project.json — the model file (import this into the web app)
  • crayon-c4-provenance.json — re-run sidecar that makes merges rename-safe
  • crayon-c4-enrichment.json — optional directives for a downstream description filler
✓ Detected: Next.js
✓ Wrote crayon-c4-project.json (4 systems · 7 containers · 23 components · 31 relationships)

No configuration is required. The same code always produces the same output (deterministic).

Scoping to specific apps

By default every Next.js app / .NET solution under the repo becomes a system. In a monorepo (or a repo that vendors sample apps), narrow the analysis with --root — repeat it for several:

npx crayon-c4 . --root apps/web --root services/billing

Roots can also be set once in the project config (static.roots). Either way, only files under the named roots are analyzed, so unrelated sub-apps never appear as phantom systems.

Set up settings without writing JSON — crayon-c4 init

A big repo can generate a diagram with 200 boxes, which communicates nothing. init measures what you'd get, proposes the test/sample projects worth dropping, and writes .crayon/config.json for you — no AI, no editor:

npx crayon-c4 init .            # measure + show proposals (writes nothing)
npx crayon-c4 init . --yes      # apply the proposals
3 of 5 diagram(s) exceed 20 elements: Domain Library — Components (67), Web UI — Components (50), API — Components (36)

Proposed exclusions (test / sample projects):
  - Acme.QueryApi.Tests
  - Acme.Tests

Detected projects you may exclude:
  Acme.Publisher  (Container, 11 child element(s))
  Acme.QueryApi   (Container, 10 child element(s))
  …

It re-measures after writing, so you see the effect immediately — and tells you what's still over budget. Iterate by editing the file (it carries a $schema, so editors autocomplete it) and re-running init.

| flag | meaning | |---|---| | --yes | apply the proposed exclusions instead of just printing them | | --exclude "A,B" | exclude exactly these instead (--exclude "" for none) | | --granularity folder\|file | how detailed component diagrams are (see below) | | --budget N | elements per diagram to aim for (default 20) | | --dry-run | print the config that would be written |

Updating is safe: init merges — it never drops a key you set by hand, and re-running it changes nothing.

Project settings — .crayon/config.json

Per-project settings live in your repo at .crayon/config.json (the legacy root-level crayon-extract.config.json still works; .crayon wins when both exist). They travel with the repo, so every machine/editor that generates the model behaves the same. Everything is optional:

{
  "schema": 1,

  // Steer the AI passes (Enrich / Model / Fill with AI) for THIS project.
  "prompts": {
    "append": "Describe everything in payments-domain terms, in English.",
    "enrichment": "Prefer short, business-facing summaries.",
    "modeling": "Model the invoice flow first.",
    "scoped": ""
  },

  // Keep clutter projects off the diagrams, and bundle many small projects
  // into one meaningful container. Patterns are anchored globs matched against
  // the project's name, its source path, and (for whole apps in a monorepo)
  // its repo-relative root.
  "projects": {
    "exclude": ["*.Tests", "*-fixtures", "packages/*"],
    "bundles": [
      { "name": "Shared packages", "match": ["Acme.Common*"], "tech": ".NET" }
    ]
  },

  // The same two rules one level down, plus how detailed a component IS.
  "components": {
    // "folder" (default): a FOLDER is one component, its files become Code
    // (still shown at --depth code). "file": every source file is a component.
    // Next.js / React only — .NET and Java components are namespaces/packages,
    // which already group like folders, so this has no effect there.
    "granularity": "folder",
    "exclude": ["*.stories", "legacy/*"],
    "bundles": [
      { "name": "C4 Model", "match": ["c4", "canvas", "diagram"] }
    ]
  },

  // Name the entry points that deserve a FULL F4 flow diagram: an API endpoint,
  // a button/screen component, a controller. Each match gets a traced diagram
  // at METHOD level (TS/JS): every called function is its own activity, edges
  // follow the call sites in source order, fetch() calls jump to the matching
  // route handler, lanes are the containers, one kind:"call" connection per hop
  // (Simon Brown style, no return lines), and an error boundary event appears
  // wherever that step's code actually has a catch.
  "flows": {
    "entryPoints": [
      { "match": "src/app/api/checkout/**", "name": "Checkout endpoint" },
      { "match": "src/components/BuyButton.tsx", "name": "Buy click" }
    ],
    "maxDepth": 4
  },

  "static": { "roots": [], "exclude": [] }
}
  • prompts — project-scoped instructions for the AI passes. append applies to every pass; the named fields add pass-specific guidance. Editor-level settings (e.g. the VS Code crayonC4.promptAppend) are appended after these.
  • projects.exclude — a matched project (system or container) disappears from the model together with its components and every relationship touching it. The run report lists what was excluded — nothing is hidden silently.
  • projects.bundles — matched containers (per parent system) collapse into ONE container named name; their components move into it and all edges re-point to it (deduped). The bundle keeps a stable id, so re-runs merge cleanly.
  • components.granularity — the biggest readability lever for Next.js / React, where a component would otherwise be one per source file. "folder" (the default) makes a folder the component and demotes its files to Code, so --depth component shows folders and --depth code still reaches every file — nothing is lost. "file" restores one component per file. No effect on .NET / Java, whose components are namespaces / packages already.
  • components.exclude / components.bundles — exactly the projects rules, applied to components. Matched against the component's name, source path, and folder path. Use bundles to merge related modules into one meaningful box when a component diagram is still too dense.
  • flows.entryPoints — each matched element becomes a fully traced F4 diagram (replacing the default sketch flow for that entry), at method level: TS/JS follows imported-symbol call sites in source order (BuyButton → HTTP POST /api/checkout → logOrder() → chargeOrder() → taxFor()); C#/Java follows constructor, static, and typed-local instance calls between the extracted classes (PaymentController → new Invoice() → TaxRule.rateFor()), up to maxDepth hops. Boundary events appear only where the step's own source handles errors.

Shaping never changes the ids of surviving elements, so your manual curation survives re-runs exactly as before.

Options (all optional)

| Flag | Meaning | Default | |------|---------|---------| | [path] | repo to analyze | . | | --root <path> | scope analysis to a specific app/solution root (repeat for several) | whole repo | | --out <file> | model output path | <path>/crayon-c4-project.json | | --provenance <file> | provenance sidecar path | <path>/crayon-c4-provenance.json | | --starting <file> | starting model to reconcile against | — | | --exclude <globs> | extra comma-separated exclusion patterns | engine defaults | | --config <file> | extractor config | discovered (.crayon/config.json) | | --file-cap <n> | max files analyzed | engine default | | --apply | write the merged result (vs report only) | off | | --dry-run | report only, write nothing | off | | --json | machine-readable summary | human text |

Exit codes

0 success · 2 usage/config · 3 no supported stack (nothing written) · 4 invalid --starting model · 5 output failed validation (nothing written).

Validate the output

The model file conforms to the published JSON Schema (schema/crayon-c4.schema.json, Draft 2020-12):

npx ajv-cli validate -s schema/crayon-c4.schema.json -d crayon-c4-project.json

License

Free to use, for commercial and non-commercial work — see the bundled LICENSE. The source code is proprietary (not open source). The models it generates from your code are yours, unrestricted. The CRAYON-C4 web app offers a free tier with a subset of its functionality; the VS Code extension bundles this same engine.