Comparison
Squawk vs pgfence
An honest comparison of two Postgres migration linters: Squawk (Rust, raw SQL, GitLab and GitHub reporters) and pgfence (TypeScript, multi-ORM, lock modes, safe rewrites, trace mode).
What Squawk is best at
Squawk is a mature, fast Rust linter for raw Postgres SQL migrations. As of v2.54.0 (May 2026) it ships 37 lint rules, an official GitHub Action, a language server with semantic tokens, a VS Code extension, and reporters for terminal, GCC, JSON, and GitLab Code Quality. If your team writes raw .sql migrations and you want a quick, well-maintained lint pass that drops cleanly into GitHub or GitLab CI, Squawk is a strong default.
Feature comparison
| Feature | Squawk (v2.54.0) | pgfence (v0.6.0) |
|---|---|---|
| Language | Rust | TypeScript (Node.js 20+) |
| License | MIT or Apache-2.0 | MIT |
| Rule count | 36 rules | 40+ migration-safety checks |
| SQL parser | Custom CST-level parser | libpg_query (PostgreSQL's own parser) |
| Input: raw SQL | Yes | Yes |
| Input: TypeORM, Prisma, Knex, Sequelize, Drizzle | No (raw SQL only) | Yes (built-in extractors) |
| Explicit lock-mode per statement | Implicit in rule text | Yes (every statement labeled) |
| Safe rewrite recipes in output | Hints with doc links | Yes (step-by-step expand or contract sequences) |
| Trace mode (live lock verification) | No | Yes (Docker, observes pg_locks) |
| DB-size-aware risk scoring | No | Yes (stats snapshot or read replica) |
| LSP / editor integration | Yes (LSP with semantic tokens, hover, completions) | Yes (LSP: diagnostics, hover, supported quick fixes) |
| VS Code extension | Yes (sbdchd.squawk) | Yes (flvmnt.pgfence) |
| GitHub Action | Yes (first-party squawk-action) | Yes (composite action) |
| Output formats | tty, GCC, JSON, GitLab Code Quality, GitHub PR comment | tty, JSON, GitHub PR comment, SARIF |
| SARIF output (GitHub Code Scanning) | No | Yes |
| GitLab Code Quality reporter | Yes | Yes |
| Coverage line (analyzed vs unanalyzable) | No | Yes (Trust Contract) |
| Policy checks (lock_timeout, statement_timeout, tx) | Partial (require-timeout-settings, ban-concurrent-index-creation-in-transaction) | Yes (full policy suite) |
Where pgfence is honestly stronger
- ORM migration files. Squawk reads raw SQL only. If your migrations live in
queryRunner.query()calls (TypeORM), Knex.raw(), SequelizeQueryInterface, Drizzle, or Prisma's generatedmigration.sql, pgfence extracts and analyzes them directly. With Squawk you have to pipe an external tool's SQL dump. - Safe rewrite recipes. For a dangerous
ALTER TABLE ... ADD COLUMN ... NOT NULL DEFAULT volatile(), pgfence prints the four-step expand or contract sequence (add nullable, backfill, CHECK NOT VALID then VALIDATE, then SET NOT NULL) in the report itself. Squawk flags the rule and links to its docs. - Trace mode. pgfence can spin up a disposable Postgres in Docker, run the migration, observe real locks via
pg_locks(including a polling observer forCONCURRENTLYstatements), and diff system catalogs to detect table rewrites. Squawk is static-only. - SARIF and GitHub Code Scanning. pgfence emits SARIF that surfaces in GitHub's Security tab. Squawk covers GitLab Code Quality, and pgfence covers both SARIF and GitLab Code Quality.
- Trust Contract coverage line. Every pgfence report says how many statements it analyzed and which it could not, with line numbers. Squawk does not surface unanalyzable statements explicitly.
Where Squawk is honestly stronger
- General SQL lint breadth. Squawk includes useful modeling and style checks such as
prefer-bigint-over-int,prefer-text-field,prefer-timestamptz,ban-char-field, andidentifier-too-long. These are not lock-safety checks, but they are real and useful. - SQL-focused LSP. Squawk's language server offers semantic tokens, completions, and hover for general SQL authoring. pgfence's LSP is migration-focused: diagnostics, lock-mode hover, and quick fixes only.
- Mature GitLab workflow. Squawk has long-running first-party GitLab Code Quality support. pgfence has a GitLab reporter too, but Squawk is older and more proven there.
- Mature GitHub Action.
squawk-actionhas years of production use and a polished PR-comment flow. - No Node runtime. A single Rust binary. If you do not want Node in your CI image, this matters.
When to choose Squawk over pgfence
Pick Squawk if any of these apply:
- You write raw SQL migrations exclusively and do not need ORM extraction.
- You deploy on GitLab and prefer the more mature Code Quality workflow.
- You want a single Rust binary with no Node.js in your CI image.
- You want a polished SQL language server with semantic tokens and completions.
- You already have Squawk in CI and your team is happy with it. Adding pgfence on top is fine, but you do not need to switch.
See also
- Eugene vs pgfence: the other Rust option, focused on live lock tracing.
- strong_migrations vs pgfence: the Ruby/Rails original, runtime interception.
- pgrubic: a newer Python-based Postgres linter with 100+ rules. If style and modeling lints matter as much as lock safety, worth a look.
- Atlas: a different category. Schema-as-code migration planner with its own lint pass. Useful if you want declarative schema management, not just a pre-merge check.