Visual, interactive DBML renderer inside VSCode. The source of truth stays in your .dbml — this extension only reads the schema and lets you arrange tables, group them into bounded contexts, and persist that arrangement as a sibling JSON file your team can review alongside the schema itself.
Built for:
- DDD projects — every
TableGroupmaps to a bounded context you can hide, collapse, or color. - Large schemas — viewport culling + LOD rendering keeps pan/zoom smooth up to ~5000 tables.
- Git-based teams — position and group state live in a sibling JSON file with stable key ordering, so diffs are minimal and reviewable.
From the VSIX (until the Marketplace listing is live):
code --install-extension dddbml-0.1.0.vsixOpen any .dbml file, then run dddbml: Open Diagram from the command palette (or click the icon in the editor title bar). A webview opens beside the editor.
- Every
Table,Ref, andTableGroupdeclared in your DBML is parsed via the official@dbml/coreand rendered as positioned nodes with Manhattan-routed edges. - Pan: middle-click drag. Zoom: mouse wheel (or
Ctrl+=/Ctrl+-). Fit:Ctrl+1. Reset:Ctrl+0. - Auto-layout via
@dagrejs/dagrethe first time a table appears; after that, your saved positions win.
- Click + drag any table to move it. Position is written to the sidecar file after a 300 ms debounce.
- Click-drag on empty space opens a marquee selector. Selected tables get an outline.
- Drag any selected table and the whole selection moves as a group.
Shift+ marquee extends the selection.Escclears it.
- Each FK line exits from the source column's row and enters at the target column's row — not the middle of the table.
- Paths are Manhattan-routed horizontally (source side → vertical jog → target side), matching dbdiagram.io's style.
- Cardinality endpoints: crow's-foot for many (
*), perpendicular bar for one (1). - Drag the middle segment of any edge to reroute it exactly where you want it — the offset persists in the layout file.
Every TableGroup name { ... } in your DBML becomes a first-class module in the diagram:
- Container: dashed colored rectangle wrapping its member tables, with a labeled tab on top-left.
- Collapse: groups fold into a single box node with aggregated edges. Double-click the label to collapse; double-click the box to expand.
- Hide: hides the whole group (or any single table) — edges to hidden tables are omitted.
- Custom colors: per-group and per-table, via the gear icon. 20 presets + custom hex picker.
Top-right floating panel with:
- Search across group names and member tables (auto-expands matches).
- Hide all / Show all in one click.
- Collapse all / Expand all groups in one click.
- Per-group: visibility toggle, collapse toggle, color picker.
- Per-table (expand a group): individual visibility toggle.
- PK column: key icon next to the name.
- Column with a DBML
Note: sticky-note icon; hover to show the full note in a floating card next to the table. - Table-level
Note: shown next to the table name and on hover. - Flags:
NNfornot null,Uforunique.
- A grid-bucketed spatial index (512 × 512 px cells) tracks every table bounding box.
- On each pan/zoom frame the index is queried for the visible window only — unseen tables skip the render tree.
- Three level-of-detail modes selected automatically by zoom:
full(zoom ≥ 0.6): full columns.header(0.3–0.6): name only.rect(< 0.3): colored rectangle.
Double-click any table header to open the .dbml file at its Table foo { ... } declaration.
A collapsible panel hugging the bottom-center of the diagram:
- PK/FK only: hide every column that isn't a primary key or foreign key — collapses dense tables to their relational skeleton.
More actions will land here.
| Key | Action |
|---|---|
Ctrl+= / Ctrl++ |
Zoom in |
Ctrl+- |
Zoom out |
Ctrl+0 |
Reset view |
Ctrl+1 |
Fit to content |
Esc |
Clear selection |
| Middle-click drag | Pan |
| Wheel | Zoom at cursor |
All of these are scoped to the webview via activeWebviewPanelId, so they don't conflict with VSCode's own shortcuts unless the diagram is focused.
For schema.dbml, the extension reads and writes a sibling schema.dbml.layout.json:
{
"version": 1,
"viewport": { "x": -120, "y": -80, "zoom": 0.75 },
"tables": {
"public.orders": { "x": 480, "y": 80 },
"public.users": { "x": 120, "y": 80, "color": "#8b5cf6" }
},
"groups": {
"billing": { "color": "#D0E8FF" },
"identity": { "collapsed": true, "color": "#FFE4A0" }
},
"edges": {
"public.orders(user_id)->public.users(id)": { "dx": 40 }
}
}Rules the writer follows to keep Git diffs minimal:
- All keys sorted alphabetically (tables, groups, edges).
- Default flags (
hidden: false,collapsed: false) are omitted. - Coordinates are integers (no subpixel noise).
- 2-space indent, LF line endings, trailing newline.
- Atomic write: temp file + rename, so a mid-write VSCode crash never leaves you with a broken layout.
After 10 users drag 10 different tables, git diff shows exactly 10 changed lines. That's the point.
| Command | What it does |
|---|---|
dddbml: Open Diagram |
Opens the webview beside the active .dbml file. |
dddbml: Reset Layout |
Clears saved positions; re-runs auto-layout on next open. |
dddbml: Prune orphan layout entries |
Removes entries in the layout file whose table was deleted from the DBML. |
dddbml: Zoom In / Out / Reset View / Fit to Content |
Viewport commands (keyboard shortcuts above). |
- Model every bounded context as a
TableGroupin your DBML:TableGroup billing { invoices payments } - Open the diagram. Groups appear as dashed containers.
- Assign each group a color that matches your domain map (gear icon → color picker).
- When reviewing changes to a far-away context, collapse everything else — keep only the context you care about visible.
- Commit both
schema.dbmlandschema.dbml.layout.json. Reviewers see what changed and how the diagram changed in the same PR.
| Metric | Target |
|---|---|
| Parse DBML, 5000 tables | < 2 s |
| Auto-layout, 5000 tables | < 3 s |
| FPS, pan continuous 10 s | ≥ 55 avg, ≥ 30 p99 |
| Webview idle memory | < 200 MB |
| Bundle (gzipped) | < 50 KB |
Measure yourself with Developer: Open Webview Developer Tools → Performance.
- No editor in the app — you edit DBML in VSCode's text editor. The diagram always reflects the last saved file.
- Single-file projects —
!includefrom one DBML into another isn't followed yet. - Edges can cross tables — the router doesn't avoid obstacles. Manually drag the middle segment if the auto route overlaps.
- No export — SQL / PNG / SVG export is not in v1.
- Self-references — refs from a table to itself render degenerately in v1; treat as known visual oddity.
See specs/08-roadmap.md for what's planned beyond v1.
pnpm install
pnpm run build # tsc + vite build
pnpm run watch:extension # tsc --watch on extension
pnpm run watch:webview # vite --watch on webviewPress F5 from the project root in VSCode to launch an Extension Development Host with the extension loaded. Open any .dbml file in that host and run the command.
src/extension/— runs in the VSCode extension host (Node.js). Parser wrapper, layout file I/O, panel lifecycle, file watchers.src/webview/— runs in the webview (Preact). Renderer, spatial index, drag controllers, group panel, color picker, tooltip.src/shared/— types shared across the postMessage boundary.specs/— design documents (architecture, layout schema, edge routing, render pipeline, roadmap).
dist/extension/extension/extension.js— host entry (CommonJS).dist/webview/webview.js— IIFE bundle loaded into the webview.
- TypeScript (strict).
- Preact + Zustand (vanilla) — zero React overhead in the webview.
@dbml/corefor DBML parsing.@dagrejs/dagrefor auto-layout.- Vite for the webview bundle,
tscfor the extension. @vscode/vscefor packaging.
No React, no React Flow. The renderer is ~1 KLOC of custom code because we need column-aligned ports, LOD, and culling that existing libraries don't give at 5000 nodes.
Extensions on the VSCode Marketplace that also render DBML but don't persist per-table positions or support DDD workflows:
matt-meyers.vscode-dbml— syntax highlighting only; complementary, not a competitor.bocovo.dbml-erd-visualizer,PeakTech.dbml-erd-viewer,nicolas-liger.dbml-viewer,rizkykurniawan.dbml-previewer,dbdiagram.dbdiagram-vscode— rendered diagrams but without Git-friendly layout persistence, group collapse, or viewport culling at scale.
dddbml specifically fills those gaps.
Issues and PRs welcome. If you're touching the render pipeline, please update the matching file in specs/ in the same PR — those documents are the source of truth for design decisions.
MIT. See LICENSE.







