mongoose-to-erd
Turn your Mongoose schemas into entity-relationship diagrams, automatically.
Generated from a real schema
Everything below is produced at build time by the actual package — the same generateErd() call you would make yourself, rendered through D2. Nothing here is a mock-up.
Every field, constraint and method.
The schema behind it
Four models with unique constraints, references, arrays of subdocuments, embedded objects, and instance/static methods.
import mongoose from "mongoose"; const User = mongoose.model("User", new mongoose.Schema({ email: { type: String, required: true, unique: true }, name: { type: String, required: true }, roles: [String], profile: { bio: String, avatarUrl: String },})); const Post = mongoose.model("Post", new mongoose.Schema({ title: { type: String, required: true }, slug: { type: String, required: true, unique: true }, published: { type: Boolean, required: true }, author: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true }, tags: [{ type: mongoose.Schema.Types.ObjectId, ref: "Tag" }],})); // …plus Tag and Comment await mongooseToErdMain(["User", "Post", "Tag", "Comment"], mongoose.model);
What was extracted
getAllModelDefinitions() returns this typed description, which you can post-process before rendering.
- User
- 6 fields, 1 instance method(s), 1 static method(s)
- Post
- 9 fields
- Tag
- 4 fields
- Comment
- 6 fields
Usage
import mongoose from "mongoose";import { mongooseToErdMain } from "mongoose-to-erd"; import "./models/user";import "./models/post"; const { files } = await mongooseToErdMain( ["User", "Post"], mongoose.model, { outDir: "docs/diagrams", timestamp: false });
Without touching the filesystem
generateErd() hands back the SVG and D2 source so you can embed, diff or serve them — which is exactly how this page is built.
const erd = await generateErd(names, mongoose.model); erd.full.svg; // rendered SVG stringerd.full.d2; // the generated D2 sourceerd.models; // the extracted schema definitions
Catching schema drift in CI
The D2 output is deterministic, so a committed diagram can be checked for drift on every build.
const { full } = await generateErd(names, mongoose.model); if (full.d2 !== readFileSync("docs/schema.d2", "utf8")) { throw new Error("Schema changed — regenerate docs/schema.d2");}