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
| Feature | Squawk | MigrationPilot |
|---|---|---|
| Language | Rust | TypeScript |
| Safety rules | 32 | 80 (77 free, 3 paid) |
| Lock type classification | No | Yes |
| Risk scoring | No | RED/YELLOW/GREEN |
| Auto-fix | No | 12 rules |
| GitHub Action | Yes | Yes (with PR comments) |
| VS Code extension | Yes | Yes |
| Config file | .squawk.toml | .migrationpilotrc.yml |
| Output formats | Text, TSV, JSON | CLI, JSON, SARIF, Markdown |
| Production context | No | Yes (paid, 3 rules) |
| Community | ~1,000 stars, 600K downloads/mo | New project |
| License | Apache 2.0 | MIT |
| Price | Free (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:
| Check | Squawk | MigrationPilot |
|---|---|---|
| CREATE INDEX without CONCURRENTLY | prefer-create-index-concurrently | MP001 |
| NOT NULL without default | adding-not-nullable-field | MP002 |
| Volatile default value | adding-field-with-default | MP003 |
| Column type change | changing-column-type | MP007 |
| SET NOT NULL | adding-required-field | MP018 |
| FK without NOT VALID | adding-foreign-key-constraint | MP005 |
| DROP INDEX without CONCURRENTLY | prefer-drop-index-concurrently | MP009 |
| SERIAL vs IDENTITY | prefer-identity | MP015 |
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.
Top comments (0)