sqlfmt is a new opinionated SQL formatter inspired by gofmt, implementing the 'river alignment' style from The Art of PostgreSQL. It right-pads all clause keywords (select, from, where, group by, etc.) to the same column at each nesting level, creating a vertical river with expressions flowing to the right. The tool uses a tokenizer rather than an AST for robustness and comment preservation. It ships with a CLI mirroring gofmt's interface (-w, -l, -d flags), editor plugins for Emacs and Vim/Neovim, and a WebAssembly-powered web formatter (~130 KB compressed). Install via `go install github.com/dimitri/sqlfmt/cmd/sqlfmt@latest`. The style enforces lowercase keywords, trailing commas, and and/or at line starts. A correctness oracle using pganalyze/pg_query_go verifies formatting never changes query semantics.

5m read timeFrom postgr.es
Post cover image
Table of contents
The styleTry it now — no install requiredCLI usageEditor integrationWhy a tokenizer, not an ASTStatus

Questions this post answers

How does sqlfmt's river alignment style format SQL clause keywords?

River alignment right-pads every clause keyword (select, from, where, group by, having, order by) to the same column at each nesting level, so the keywords form a vertical river and expressions flow to the right. The longest keywords like group by and order by (8 characters) sit flush-left at base indent, and shorter keywords like select (6 characters) are padded to match — a side effect of the alignment rule, not a special exception. Developers maintaining hand-written SQL files track formatting tools like sqlfmt on daily.dev.

Why does sqlfmt use a tokenizer instead of an AST for SQL formatting?

Two practical reasons drive the tokenizer choice: PostgreSQL's own parser discards comments, so any AST-based formatter needs a separate comment-recovery pass that negates the parser's structural advantage. Second, a token-stream approach degrades gracefully on partial statements or invalid snippets, while a grammar-based parser fails hard — important for the web widget that must handle arbitrary pasted input. Correctness is verified separately using pganalyze/pg_query_go as an oracle. Teams enforcing SQL style in CI pipelines find relevant tooling discussions on daily.dev.

How do I enforce sqlfmt formatting in CI on only changed SQL files?

Use the -l flag, which exits with code 1 if any file's formatting would change without rewriting it. The command `sqlfmt -l $(git diff --name-only '*.sql')` checks only the SQL files modified in the current diff, making it suitable as a pull request gate that enforces style without storing formatted output in the pipeline. Engineers setting up SQL linting in pull request pipelines find related tooling news on daily.dev.

27.3K Impressions