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

excalidraw-gen

v0.1.3

Published

CLI tool to generate Excalidraw-compatible JSON diagrams from structured input specs

Readme

excalidraw-gen

A CLI tool that generates Excalidraw-compatible .excalidraw JSON files from structured JSON or YAML input specs.

Define your diagram with nodes, edges, types, colors, sizes, and arrow styles — get a fully-formed Excalidraw diagram you can open immediately in the browser or desktop app.


Features

  • JSON and YAML input — both formats supported natively
  • Per-node style overrides — color, size, shape, opacity, fill pattern, border style
  • Per-edge style overrides — stroke color, dash style, thickness, opacity
  • DAG layout — BFS layered layout with Kahn's algorithm (handles cyclic graphs without hanging)
  • Dynamic node sizing — node height auto-expands for multi-line or long labels
  • Grid layout — simple √n-column grid for non-hierarchical diagrams
  • Two templatesflowchart and architecture with distinct node styles
  • Three themesdefault, pastel, dark
  • Step-routed elbow arrows — clearly exit the correct edge of the source node
  • Accurate arrow labels — labels placed at the geometric midpoint of the elbow path
  • Pre-flight validation — catches Excalidraw JSON issues before writing the file

Installation

npx (no install required)

Run directly without installing anything:

npx excalidraw-gen generate diagram.json --out out.excalidraw

Global install

npm install -g excalidraw-gen
excalidraw-gen generate diagram.json --out out.excalidraw

From source

git clone https://github.com/fizznix/excalidraw-gen.git
cd excalidraw-gen
npm install
npm run build
npm link   # makes excalidraw-gen available globally

Usage

excalidraw-gen generate <input> [options]

| Option | Default | Description | |---|---|---| | --template | flowchart | flowchart or architecture | | --theme | default | default, pastel, or dark | | --layout | dag | dag or grid | | --out | stdout | Output file path (.excalidraw) | | --max-nodes <n> | 200 | Reject diagrams with more nodes than this |

Examples

# JSON flowchart
excalidraw-gen generate examples/simple-flowchart.json \
  --template flowchart --out out/flow.excalidraw

# YAML input
excalidraw-gen generate examples/pipeline.yaml --out out/pipeline.excalidraw

# Architecture diagram with dark theme
excalidraw-gen generate examples/architecture.json \
  --template architecture --theme dark --out out/arch.excalidraw

# Styled flowchart with per-node/edge colors
excalidraw-gen generate examples/styled-flowchart.json --out out/styled.excalidraw

# Print to stdout (pipe-friendly)
excalidraw-gen generate examples/simple-flowchart.json

Open the .excalidraw file at excalidraw.com via Open → select file.


Input Format

Input can be JSON or YAML. Both support the same fields.

JSON

{
  "type": "flowchart",
  "title": "My Diagram",
  "nodes": [
    {
      "id": "start",
      "label": "Start",
      "type": "start",
      "style": {
        "backgroundColor": "#a5d8ff",
        "strokeColor": "#1971c2",
        "shape": "ellipse",
        "width": 160,
        "height": 60
      }
    },
    { "id": "process", "label": "Do Something", "type": "process" },
    {
      "id": "decide",
      "label": "OK?",
      "type": "decision",
      "style": { "strokeStyle": "dashed", "strokeWidth": 3 }
    },
    { "id": "end", "label": "End", "type": "end" }
  ],
  "edges": [
    { "from": "start", "to": "process" },
    { "from": "process", "to": "decide", "label": "Check" },
    {
      "from": "decide",
      "to": "end",
      "label": "Yes",
      "style": { "strokeColor": "#2f9e44", "strokeWidth": 2 }
    }
  ]
}

YAML

type: flowchart
title: My Diagram

nodes:
  - id: start
    label: Start
    type: start
    style:
      backgroundColor: "#a5d8ff"
      strokeColor: "#1971c2"
      shape: ellipse

  - id: process
    label: Do Something
    type: process

edges:
  - from: start
    to: process
    label: Go
    style:
      strokeColor: "#7048e8"
      strokeStyle: dashed

Style Overrides

Per-node style fields

| Field | Type | Description | |---|---|---| | backgroundColor | string | Fill color (hex, e.g. "#ff6b6b" or "transparent") | | strokeColor | string | Border color | | strokeWidth | number | Border thickness in px | | strokeStyle | "solid" | "dashed" | "dotted" | Border style | | fillStyle | "solid" | "hachure" | "cross-hatch" | "zigzag" | Fill pattern | | shape | "rectangle" | "ellipse" | Override the template shape | | width | number | Node width in px | | height | number | Node height in px (auto-computed if omitted) | | opacity | number | Opacity 0–100 |

Per-edge style fields

| Field | Type | Description | |---|---|---| | strokeColor | string | Arrow color | | strokeStyle | "solid" | "dashed" | "dotted" | Line style | | strokeWidth | number | Thickness in px | | opacity | number | Opacity 0–100 |


Node Types

Flowchart template

| Type | Default style | |---|---| | start / end | Ellipse | | process | Rectangle (purple) | | decision | Dashed orange rectangle | | io | Rectangle (teal) | | subprocess | Rectangle (green) |

Architecture template

| Type | Default style | |---|---| | service / api | Rectangle (purple) | | db / database | Rectangle (green) | | queue | Rectangle (yellow) | | cache | Rectangle (orange) | | gateway / orchestrator | Bold rectangle (red) | | frontend | Rectangle (blue) | | user / actor | Ellipse | | external | Rectangle (light red) | | ml / ai | Rectangle (purple haze) | | monitor | Rectangle (green) |

Note: No diamond shape exists in Excalidraw raw JSON. Decision nodes use a dashed orange rectangle as the canonical alternative.


Development

Scripts

npm run build        # Compile TypeScript → dist/
npm run dev          # Run directly via ts-node (no build needed)
npm test             # Run all tests (vitest)
npm run test:watch   # Watch mode
npm run lint         # Type-check without emitting

Project structure

src/
  cli.ts              # Commander CLI entrypoint
  types/              # Shared TypeScript types (NodeStyle, EdgeStyle, etc.)
  parser/             # JSON + YAML input → Diagram object
  validator/          # Input validation (errors + warnings)
  normalizer/         # Defaults, ID cleanup, duplicate-edge detection
  layout/
    dag.ts            # Kahn's topological sort + BFS DAG layout
    grid.ts           # Grid layout
    arrow-router.ts   # Elbow arrow anchor + step point calculation
  renderer/
    elements.ts       # Shape / text / arrow element factories (with style merging)
    index.ts          # Full render orchestration
    seed.ts           # Deterministic ID hashing (FNV-1a)
  templates/
    index.ts          # flowchart + architecture template definitions
    themes.ts         # default / pastel / dark color overlays
  exporter/           # Assemble ExcalidrawFile, pre-flight check, write
  validator/
    preflight.ts      # Post-render element sanity checks
examples/
  simple-flowchart.json    # 5-node login flow
  styled-flowchart.json    # Payment flow with per-node/edge style overrides
  architecture.json        # 8-node 3-tier web app
  pipeline.yaml            # CI/CD pipeline (YAML format)

Contributing

1. Fork and clone

git clone https://github.com/your-username/excalidraw-gen.git
cd excalidraw-gen
npm install

2. Create a branch

git checkout -b feat/your-feature-name

Use a descriptive prefix: feat/, fix/, docs/, test/, refactor/.

3. Make your changes

  • Keep changes focused — one concern per PR
  • Match the existing code style (TypeScript strict mode, no any)
  • Do not add comments or docstrings to code you didn't change

4. Run tests and build

npm run build && npm test

Both must pass with zero errors before submitting.

5. Submit a pull request

Open a PR against main with a clear description of what changes and why.

Adding a new template

  1. Add a TemplateDefinition in src/templates/index.ts using registerTemplate()
  2. Add theme overrides in src/templates/themes.ts if needed
  3. Add an example JSON or YAML file under examples/
  4. Add tests in tests/renderer.test.ts

Adding a new layout engine

  1. Implement (diagram: Diagram) => LayoutNode[] in src/layout/
  2. Register it in src/layout/index.ts using registerLayoutEngine()
  3. Add tests in tests/layout.test.ts

Known Excalidraw raw JSON constraints

  • No type: "diamond" — use dashed rectangles for decision nodes
  • Labels require two elements: the shape with boundElements + a separate text with containerId
  • Arrows must have roughness: 0, roundness: null, elbowed: true
  • Arrow x, y is the edge point of the source shape, not the center
  • points[0] is always [0, 0]; all other points are relative offsets

License

MIT