Interactive live-preview editor for DBML files. Point it at a file or directory; it opens a browser with a syntax-highlighted editor on the left and a rich ER diagram on the right. Edits happen in the browser and are persisted explicitly with ⌘/Ctrl+S.
# Run without installing
npx dbml schema.dbml
# Or install globally
npm install -g dbml
dbml schema.dbmldbml <file-or-dir> [more files] [options]Examples:
dbml schema.dbml # single file
dbml users.dbml posts.dbml # multiple files
dbml ./db/schemas/ # directory — loads every *.dbml
dbml schema.dbml --port 3000 # custom port
dbml new.dbml --create # create starter file if missingOptions:
--port <n>— port to serve on (default4477; auto-increments if busy)--no-open— don't auto-open the browser--create— create the file with a starter template if it doesn't exist (single-file only)--review— open in review mode for AI agent feedback loops (see below)
- Interactive ER diagram — draggable table nodes, auto-routed edges, zoom, pan
- Hover popover — each column reveals a detail panel with type, constraints (Primary / Not null / Autoincrement / Unique), default, and comment
- CodeMirror 6 editor with DBML syntax highlighting and inline error markers
- Explicit save — edits stay in the browser until you hit ⌘S/Ctrl+S or click Save
- Stale-disk detection — if the file changed on disk since load, you get a prompt to overwrite or reload
- Parse errors — surfaced with exact line/column, highlighted in the editor
- Reset layout — one-click return to dagre auto-layout after dragging
- Resizable split pane — drag the divider; width persists across reloads
- Multi-file / directory mode — sidebar lists every
.dbmlfile, switch between them with unsaved state preserved per file - Dark mode — follows
prefers-color-schemewith a manual toggle - PNG / SVG export — one click to download the current canvas
- Atomic writes — writes go through a
.tmpfile andrename(), so a crash mid-write won't truncate your file - Port auto-fallback — if the requested port is busy, the next free one is used automatically
dbml schema.dbml --review opens a special review layout designed for AI-agent feedback loops:
- The left pane is the read-only DBML editor (you can select text but can't edit it)
- The right pane is the interactive ER diagram preview
- The topbar gains an annotations drawer toggle, Approve, and Send feedback buttons
- The process blocks until the user clicks Approve or Send feedback
The flow is:
- User reviews the schema visually in the diagram and textually in the editor
- User drags to select one or more lines in the editor — anything from a single column to a whole
Table { … }block to aRef:line - An inline popup opens just below the selection with the captured snippet and a textarea
- User types a note and presses
⌘/Ctrl+Enter(or clicks Add note) to attach it to the range - Annotated lines get a persistent amber bar in the editor for at-a-glance review
- Open the Annotations drawer (topbar button, with badge showing the count) to see / delete / jump back to existing annotations
- Click an annotation in the drawer to scroll the editor to its range and re-open the popup pre-filled with the existing note for quick editing
- Annotations persist to
localStorage— refreshing or accidentally closing the tab doesn't lose your work - When done, click Approve (no changes needed) or Send feedback (delivers all annotations to the agent)
When the user submits, the CLI prints a structured markdown report to stdout and exits with code 0:
# Schema review: CHANGES REQUESTED
The user reviewed the proposed schema and left annotations below.
Each annotation references a specific file and (optionally) a range of
lines with a snippet of the original source. Update the DBML files to
address every annotation faithfully, then re-run the review if needed.
## Reviewed files
- /abs/path/to/schema.dbml
## Annotation 1 — `schema.dbml` (lines 12–15)
Selected source:
```dbml
Table projects {
id integer [pk, increment]
owner_id integer [not null]
name varchar [not null]
```
User note:
> Owner relationship should be ON DELETE CASCADE.
> Also add a slug column with unique index.The agent reads each ## Annotation N block, locates the snippet in the file, and applies the user's note literally.
The agent receives the exact lines the user selected, snippet and all, instead of pointing at a single column or table. That makes batch feedback like "split these three columns into a profile table" or "rewrite this whole Ref: chain" expressible in one annotation. The snippet also lets the agent locate the spot in the file even after earlier edits have shifted line numbers.
A ready-to-use slash command lives in examples/dbml-review.md. Drop it into your project's .claude/skills/<your-skill>/commands/ directory and invoke with /dbml-review schema.dbml.
Stderr is used for startup logs in review mode so stdout stays clean for the feedback payload — no escaping or filtering needed in your slash command.
- CLI resolves positional args into a list of allowed file paths and starts a local HTTP server
- Server exposes
GET /api/files,GET /api/file?path=…,POST /api/file, andPOST /api/parse— path arguments are validated against the allowed set to prevent traversal - DBML parsing runs server-side via
@dbml/core, so the browser bundle stays small (~700 KB JS, 240 KB gzipped) - Frontend uses React + React Flow + CodeMirror 6 + dagre; all vendor chunks are split for caching
npm install
npm run build # one-off build
npm run dev # Vite dev server on :5173 (proxies /api to :4477)
node bin/dbml.mjs sample.dbml # run the CLI against the sample fileThe Vite dev server proxies /api/* to the CLI-started server on :4477. Start both for an HMR workflow.
MIT