11 min read

Squawk vs MigrationPilot: PostgreSQL Migration Linters Compared

Squawk and MigrationPilot are both open-source PostgreSQL migration linters. Both analyze SQL files for dangerous operations and both integrate with CI. But they differ significantly in approach, rule depth, and what information they give you. This comparison is published on the MigrationPilot blog — take that into account and verify claims against the source code of both tools.

Quick Comparison

FeatureSquawkMigrationPilot
LanguageRustTypeScript
Safety rules3280 (77 free, 3 paid)
Lock type classificationNoYes
Risk scoringNoRED/YELLOW/GREEN
Auto-fixNo12 rules
GitHub ActionYesYes (with PR comments)
VS Code extensionYesYes
Config file.squawk.toml.migrationpilotrc.yml
Output formatsText, TSV, JSONCLI, JSON, SARIF, Markdown
Production contextNoYes (paid, 3 rules)
Community~1,000 stars, 600K downloads/moNew project
LicenseApache 2.0MIT
PriceFree (100%)Free (97% of rules), $19/mo for production context

Where Squawk Is Better

Let's start with where Squawk wins. Being honest about this matters more than marketing.

1. Speed

Squawk is written in Rust and is fast. For typical migration files (1-50 statements), both tools complete in under a second, so this doesn't matter in practice. But if you have very large migration files (thousands of statements), Squawk's Rust parser will be noticeably faster than MigrationPilot's TypeScript + WASM parser.

2. Maturity and community

Squawk has ~1,000 GitHub stars and ~600,000 downloads per month. It has been used in production by many teams for years. MigrationPilot is a new project with a small community. If you value battle-tested stability and want a tool that has already encountered and handled edge cases in the wild, Squawk has a significant advantage.

3. 100% free

Squawk is completely free with no paid tier. Every feature is available to everyone. MigrationPilot has 3 rules (out of 80) that require a $19/month subscription. While 97% of MigrationPilot's rules are free, Squawk's fully-free model is simpler and carries no risk of future paywall expansion.

Where MigrationPilot Is Better

1. Rule depth (80 vs 32)

MigrationPilot has 80 safety rules compared to Squawk's 32. The additional 48 rules cover:

  • Data safety: TRUNCATE TABLE, DROP CASCADE, unvalidated enum changes
  • Best practices: VARCHAR vs TEXT, TIMESTAMP vs TIMESTAMPTZ, missing IF NOT EXISTS
  • Lock safety: VACUUM FULL, LOCK TABLE, DISABLE TRIGGER, CLUSTER
  • Partition safety: partition key in PK, detach partition concurrently
  • Extension safety: PostGIS spatial indexes, pgvector HNSW vs IVFFlat
  • Transaction safety: uncommitted transactions, concurrent ops in transactions

The core rules overlap substantially — both tools catch CREATE INDEX without CONCURRENTLY, volatile defaults, and column type changes. The difference is in the long tail: patterns that are less common but equally dangerous when they occur.

2. Lock type classification

When MigrationPilot flags a dangerous statement, it tells you which lock the statement acquires. This is important because different locks have different impacts:

# MigrationPilot output
  MP001 [critical] CREATE INDEX without CONCURRENTLY
    Acquires: SHARE lock (blocks writes, allows reads)
    Table: orders
    Safe alternative:
      CREATE INDEX CONCURRENTLY idx_orders_customer ON orders (customer_id);

# Squawk output
migrations/001.sql:1:1: warning: prefer-create-index-concurrently
  Instead of `CREATE INDEX`, use `CREATE INDEX CONCURRENTLY`.

Squawk tells you the operation is dangerous and suggests the fix. MigrationPilot also tells you the specific lock type (SHARE, ACCESS EXCLUSIVE, SHARE UPDATE EXCLUSIVE, etc.), which helps you understand the actual impact on running queries. A SHARE lock blocks writes but allows reads; an ACCESS EXCLUSIVE lock blocks everything.

3. Auto-fix

MigrationPilot can automatically fix 12 rule violations:

# Preview what would change
npx migrationpilot analyze migration.sql --fix --dry-run

# Apply fixes directly
npx migrationpilot analyze migration.sql --fix

# Example: MP001 auto-fix
# Before: CREATE INDEX idx_orders_customer ON orders (customer_id);
# After:  CREATE INDEX CONCURRENTLY idx_orders_customer ON orders (customer_id);

Squawk does not have auto-fix. It reports the violation and links to documentation, but you make the change manually. For the 12 rules MigrationPilot can auto-fix, the fix is a deterministic text transformation — not a heuristic guess.

4. Risk scoring and prioritization

MigrationPilot assigns a risk score to each migration: RED (critical — likely to cause outage), YELLOW (warning — may cause issues), GREEN (safe). This helps teams with many migration files prioritize which ones to fix first.

Squawk reports violations with severity levels but does not provide an aggregate risk score for the migration as a whole.

5. Multiple output formats

MigrationPilot outputs in four formats:

  • CLI: Colored terminal output with lock types, timing, and risk scores
  • JSON: Structured, versioned schema for programmatic consumption
  • SARIF: For GitHub Code Scanning and IDE integration
  • Markdown: For documentation, wikis, or PR comments

SARIF output is particularly useful — it integrates with GitHub's Code Scanning to show violations directly in the "Files changed" tab of pull requests. Squawk outputs in text, TSV, and JSON formats.

Rule Overlap

Most of Squawk's 32 rules have equivalents in MigrationPilot. Here are the key mappings:

CheckSquawkMigrationPilot
CREATE INDEX without CONCURRENTLYprefer-create-index-concurrentlyMP001
NOT NULL without defaultadding-not-nullable-fieldMP002
Volatile default valueadding-field-with-defaultMP003
Column type changechanging-column-typeMP007
SET NOT NULLadding-required-fieldMP018
FK without NOT VALIDadding-foreign-key-constraintMP005
DROP INDEX without CONCURRENTLYprefer-drop-index-concurrentlyMP009
SERIAL vs IDENTITYprefer-identityMP015

The overlap confirms that both tools catch the most critical migration safety issues. The difference is in coverage breadth: MigrationPilot has 48 additional rules for patterns that Squawk does not check.

CI Integration

Both tools provide GitHub Actions. Here is how they look in a workflow:

Squawk GitHub Action

- uses: sbdchd/squawk-action@v1
  with:
    pattern: "migrations/*.sql"

MigrationPilot GitHub Action

- uses: mickelsamuel/migrationpilot@v1
  with:
    paths: "migrations/*.sql"
    fail-on: critical

Both actions post comments on pull requests with the violations found. MigrationPilot additionally provides inline annotations in the "Files changed" tab and a Job Summary with aggregate metrics. Squawk's action is simpler and more focused.

Known Limitations

Squawk's known issues

  • Cannot analyze PL/pgSQL function bodies or DO blocks (GitHub issues #411, #528)
  • False positives in some valid contexts (#937, #973)
  • Exit code 1 for both errors and warnings — no way to distinguish (#348)
  • No cross-file validation or schema-level context
  • Pre-commit integration has been broken since June 2024 (#363)

MigrationPilot's known issues

  • New project — fewer real-world battle-testing hours
  • TypeScript is slower than Rust on very large files (sub-second for typical use)
  • Small community — fewer contributors finding and fixing edge cases
  • 3 rules behind a paywall ($19/month for production context analysis)
  • No dynamic lock tracing (purely static analysis, like Squawk)

When to Use Squawk

  • You want a proven, battle-tested tool. Squawk has years of production usage and a larger community. If stability and track record matter most, use Squawk.
  • You want 100% free with zero paid components. Squawk is fully free with no paid tier.
  • You need Rust-native speed. If you lint thousands of migration files in CI, Squawk's Rust parser is faster.
  • You want minimal dependencies. Squawk is a single binary. MigrationPilot requires Node.js.

When to Use MigrationPilot

  • You want the most comprehensive rule set. 80 rules cover patterns that Squawk's 32 rules do not check.
  • You want lock type information. Knowing which lock a statement acquires helps you assess real-world impact.
  • You want auto-fix. 12 rules can be automatically fixed with --fix.
  • You want SARIF output for GitHub Code Scanning. Violations appear directly in PR diffs.
  • You need production context analysis. Table size and query impact awareness (paid tier) is unique to MigrationPilot.
  • You want config presets. Five built-in presets (recommended, strict, ci, startup, enterprise) for different deployment contexts.

Can You Use Both?

Yes. Both tools analyze plain SQL files and can run independently in CI. Running both gives you the union of their rule sets and two independent opinions on each migration. The overhead is minimal — both complete in under a second for typical migrations.

# Run both in CI
- name: Squawk lint
  uses: sbdchd/squawk-action@v1
  with:
    pattern: "migrations/*.sql"

- name: MigrationPilot lint
  uses: mickelsamuel/migrationpilot@v1
  with:
    paths: "migrations/*.sql"
    fail-on: critical

Summary

  • Squawk is the established choice: proven, fast, 100% free, and sufficient for catching the most common PostgreSQL migration hazards.
  • MigrationPilot offers more coverage: 80 vs 32 rules, lock type classification, auto-fix, risk scoring, and SARIF output. But it's newer and less battle-tested.
  • Both tools catch the critical issues (missing CONCURRENTLY, volatile defaults, column type changes, SET NOT NULL).
  • The core rules overlap significantly. The difference is in the long tail of less common but still dangerous patterns.
  • If stability and simplicity matter most, use Squawk. If coverage and features matter most, try MigrationPilot. If you want maximum safety, use both.