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 in Ref endpoints, column names after table., inline-ref targets, TableGroup bodies, and Project { 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!