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

@castachick/erd

v0.2.1

Published

Decompose PostgreSQL schemas into readable Mermaid ER diagrams

Readme

@castachick/erd

npm version Node.js version

English | 日本語

A CLI that reads a live PostgreSQL schema and splits related tables into readable Mermaid ER diagrams, with SVG previews. It works independently of ORMs and migration files and never reads table rows.

Preview

An example with seven fictional store tables: customers, orders, order items, payments, products, categories, and inventory. These SVGs are generated by the same API used by the CLI.

Overview

The overview shows every selected table and foreign key without columns.

ER overview of a fictional store

Detail diagram

Related tables are grouped around a hub. A neighboring table from another group appears as context, so relationships remain visible across groups.

Order detail diagram with columns and a product context table

Browse all diagrams and Mermaid sources · Example generator

To regenerate the example from the repository checkout, run npm ci and npm run docs:example. No database is needed; Chrome is required as described below. The example uses maxTables: 4, maxContextTables: 1, and columns: 'all'. When changing documentation or examples, update both language versions together.

Installation

Requires Node.js 20 or later.

npm install -g @castachick/erd
export DATABASE_URL='postgresql://user:password@localhost:5432/app'
erd --schema public --max-tables 15 --out ./docs/erd

For a project-local development dependency, use npm install -D @castachick/erd and run npx erd. For a one-off run, use npx --package @castachick/erd erd --schema public.

SVG generation uses Chrome managed by Puppeteer. It is normally downloaded during npm installation, increasing the download size. If the download was skipped, install the matching browser:

npx --package [email protected] puppeteer browsers install chrome

To use an existing Chrome installation, set PUPPETEER_EXECUTABLE_PATH to its executable. Linux also requires Chrome's shared libraries. SVG rendering runs locally; database schemas are never sent to an external rendering service.

Developing from source

npm ci
npm run build
export DATABASE_URL='postgresql://user:password@localhost:5432/app'
node dist/cli.js --schema public --max-tables 15 --out ./docs/erd

During development, you can also run npm run dev -- --schema public --out ./docs/erd. Installing the package globally makes the erd command available:

npm install -g .
erd --schema public --schema auth --out ./docs/erd

Options

| Option | Default | Description | | --- | --- | --- | | --database-url <url> | DATABASE_URL | Connection URL; an explicit value takes precedence | | --schema <schema> | public | Schema to include; repeatable | | --out <directory> | ./erd | Output directory | | --max-tables <number> | 15 | Maximum primary tables per diagram; at least 1 | | --context-depth <number> | 1 | Include neighboring tables; 0 or 1 | | --max-context-tables <number> | 5 | Maximum additional context tables; at least 0 | | --columns <all\|keys\|none> | keys | All columns, PK/FK/UNIQUE columns, or no columns | | --cardinality <inferred\|simple> | inferred | Infer from constraints, or show 0..N at both ends | | --include-table <glob> | All | Match a table name or schema.table; repeatable | | --exclude-table <glob> | None | Exclude matching tables; repeatable; overrides include | | --help | | Show usage |

erd --schema public --exclude-table '__drizzle_*' --columns keys --out ./docs/erd

Quote globs to prevent shell expansion. System schemas are excluded. Application tables are never implicitly excluded, so explicitly filter out migration tracking tables if needed.

Output

docs/erd/
├── index.md
├── overview.mmd
├── overview.svg
├── 02-orders.mmd
├── 02-orders.svg
├── 01-products.mmd
├── 01-products.svg
└── graph.json

Diagram names depend on the selected schema and grouping. index.md embeds the overview and detail SVGs, lists hubs, primary and context tables, and warnings, and links to standalone SVGs and Mermaid sources. Every .mmd has a matching .svg. Mermaid sources can also be opened in a Mermaid-compatible viewer. The overview shows all selected tables and foreign keys without columns; detail diagrams label hubs and context tables. graph.json preserves original types, column order, composite PK/UNIQUE/FK constraints, referential actions, and communities (table groups).

With the same database state, options, dependency versions, and Chrome/font environment, output is deterministic and contains no timestamps. SVG dimensions and layout can vary by OS or fonts. If SVG rendering fails, the command exits with an error without writing a new index. Generated files with matching names are overwritten. Old diagrams and user files are not deleted; after changing grouping options, use index.md as the current list of diagrams.

Grouping and relationship interpretation

  • Analysis uses a simple undirected graph with a weight of 1 per FK constraint. Multiple FKs between a table pair add weight; a composite FK counts as one.
  • Louvain runs in a fixed order, and oversized communities are split again. If splitting fails, a greedy fallback adds strongly connected neighbors in sequence.
  • Every table belongs to exactly one primary group. Hubs are selected by internal neighbor count, total neighbor count, then table ID.
  • Context tables are selected by FK count to the primary group, direct connection to the hub, total neighbor count, then ID. Relationships between context tables and two-hop relationships are omitted.
  • max-tables limits primary tables only. The total limit per diagram is max-tables + max-context-tables.
  • Tables with no connections to other selected tables are collected into an isolated group. Self-referencing FKs do not contribute to analysis weights but remain in diagrams and JSON.
  • FKs to excluded tables or schemas remain in JSON but are omitted from diagrams with a warning. Add required schemas with --schema.

The parent end is 1 when all FK columns are NOT NULL, otherwise 0..1. The child end is 0..1 if the FK column set contains every column of a PK or UNIQUE constraint, otherwise 0..N. A relationship is solid when all FK columns belong to the child's PK, otherwise dashed.

Mermaid's UK marker also appears on members of composite UNIQUE constraints, with a comment identifying their membership. It does not mean that each column is individually unique; see JSON for the original constraints. Names and types containing special characters are normalized for Mermaid, while labels, column comments, and JSON preserve original names.

Supported relations are ordinary and partitioned tables, including child partitions. Views, materialized views, foreign tables, standalone unique indexes that are not UNIQUE constraints, FK MATCH FULL semantics, and application-level relationships are not inferred. The simple mode shows 0..N at both ends and is only a structural overview. Identifiers containing dots or other special characters use SQL-style quoting in JSON table IDs to avoid collisions.

Safety and errors

Metadata is read in a REPEATABLE READ READ ONLY transaction, with a 10-second connection timeout and a 30-second SQL timeout. The connection user needs permission to inspect metadata in the selected schemas. Credentials and connection URLs are excluded from generated files and logs, and raw database-driver errors are not displayed.

Connection failures, nonexistent schemas, empty selections, output failures, and invalid options exit with code 1. Omitted external FKs, isolated tables, and fallback grouping produce warnings.

Validation

npm run check
npm test
npm run build

The regular test suite covers graph invariants, determinism, composite constraints, cardinality, CLI argument validation and credential redaction, syntax validation with the real Mermaid parser, Chrome SVG rendering, deterministic SVGs, matching Mermaid/SVG files, and image references in the index. Chrome is required for regular tests too.

PostgreSQL integration tests require a dedicated test database and are skipped when none is configured. They create temporary schemas in that database and remove them afterward. Tested with PostgreSQL 16.

TEST_DATABASE_URL='postgresql://localhost/erd_test' npm run test:integration

Integration tests cover composite FK ordering, duplicate constraint names, multiple schemas, types and nullability, partitions, CLI output and repeatability, and failure cases.

Architecture

src/postgres handles SQL and connections; src/schema-graph defines and filters the intermediate model; src/analysis groups tables; and src/render produces Mermaid, JSON, and the index. generate() is a synchronous, browser-free API that returns Mermaid, JSON, and a link-based index. await generateWithSvg() also returns SVGs and an index with embedded images. run() and the CLI handle everything from database introspection to writing all output files, including SVGs.

The design reference is the handoff document (Japanese). Relationship notation follows the official Mermaid syntax; Louvain settings follow the Graphology documentation and the installed package's declarations and implementation.

Publishing to npm (maintainers)

The package name is @castachick/erd. publishConfig selects the official npm registry and public access.

After merging, run the following on the latest main branch:

npm ci
npm run test:package
npm publish --dry-run
# Review the package contents and version before publishing.
npm publish

test:package creates a tarball, installs it with production dependencies in a temporary directory, and verifies the CLI, ESM API, and SVG generation. Temporary files are removed afterward. During npm publish, prepublishOnly runs type checking and tests, and prepack rebuilds dist. The package includes dist, both READMEs, generated example output, LICENSE, and package.json; development sources and tests are excluded.

To also run database integration tests, set TEST_DATABASE_URL to a dedicated database. They are skipped otherwise. A dry run does not guarantee successful publishing or two-factor authentication. Follow npm's authentication instructions when prompted.

For each release, update to an unpublished version; an existing version cannot be republished. After publishing, verify with npm view @castachick/erd version and npx --package @castachick/erd erd --help.

License

Licensed under the MIT License.