A while ago I wrote about dbml-tools, a Go CLI for converting between live databases, DBML, SQL, and Graphviz diagrams. The CLI works fine in a terminal, but the moment you start editing DBML files by hand you want the usual editor niceties: red squiggles when you mistype a column, jump-to-definition on a foreign key, rename a table without hunting through references. That is what the DBML Tools VSCode extension delivers.
dbml-tools now ships an lsp subcommand that speaks the Language Server
Protocol, and there is a matching VSCode extension that drives it.
See: VSCode Marketplace or Open VSX
What the extension does
The extension registers .dbml as a language and starts dbml-tools lsp over
stdio. With both installed you get:
- Syntax highlighting for tables, enums, refs, table groups, project settings, attributes, builtin types, strings, comments, color literals, and relationship operators.
- Live diagnostics: parse and semantic errors appear as red squiggles as you type.
- Hover on a table, column, enum, alias, builtin type, or attribute shows its definition and constraints.
- Context-aware completions for top-level keywords, builtin types and
declared enums in column-type position, attribute names inside
[ ... ], table names inRefendpoints, column names aftertable., inline-ref targets,TableGroupbodies, andProject { database_type: ... }values. - Go-to-definition (F12) on a ref endpoint, alias, or enum-as-type.
- Find all references (Shift+F12) from any symbol.
- Rename (F2) across the whole file. Names that need quoting are wrapped in
"..."automatically. - Document outline for the file’s tables and enums, visible in the outline view and breadcrumb bar.
- Snippets for the common shapes:
table,tablefk,ref,enum,proj,tg.
Why split the work between a CLI and an extension?
A VSCode extension can do everything in TypeScript, but then you end up
maintaining two parsers: one in Go for the CLI, one in TypeScript for the
editor. They drift, diagnostics differ between dbml-tools check and the
editor, and every new feature has to be implemented twice.
LSP avoids that. The Go binary owns the lexer, parser, interpreter, and analysis
layer. The extension is a thin client that forwards keystrokes and renders the
responses. The same code that powers dbml-tools check on the command line
powers the squiggles in the editor. If your CI fails on a parse error, you see
the exact same message in VSCode.
It also means the heavy lifting can be reused by other editors. Anything that
speaks LSP, like Neovim, Helix, or Zed, can point at dbml-tools lsp and get
the same features. The extension is just the wiring for VSCode.
Installation
Install the extension from the Marketplace by searching for “DBML Tools”, or from the command line:
code --install-extension tqdev-com.dbml-tools
That is all. The extension ships with prebuilt dbml-tools binaries for Linux,
macOS, and Windows (x64 and arm64) and uses the one that matches your platform.
It activates the first time you open a .dbml file.
If you would rather use your own binary, the resolution order is dbml.path in
your settings, then dbml-tools on $PATH, then the bundled binary. So to
override, either set dbml.path to an absolute path or install your own:
go install github.com/mevdschee/dbml-tools@latest
Try it
Open a new schema.dbml and type:
Project myapp {
database_type: 'PostgreSQL'
}
Table users as u {
id int [pk, increment]
email varchar(255) [not null, unique]
status order_status
}
Enum order_status {
pending
shipped
cancelled
}
Ref: orders.user_id > u.id
Hover over order_status on the status column and you see the enum’s values.
Press F12 on u.id in the Ref line and you jump to the users table. Press
F2 on users and rename it everywhere in the file in one go. Inside [ ... ],
press Ctrl+Space and you see pk, unique, not null, default, note,
ref.
The Ref: orders.user_id > u.id line will show a diagnostic, because there is
no orders table in the file yet. Add one and the squiggle disappears.
What is next
The project is brand new and requires thorough testing. If you want to help test on Windows or macOS, file an issue on GitHub. The binary builds for all three platforms, but I mostly use it on Linux.
Enjoy!