A fast SQL linter written in Rust. The Ruff for SQL.
Catches unused CTEs, SELECT *, unsafe casts, duplicate joins, and hundreds more — in 18ms. 330 rules across 6 categories.
If you use sqlfluff, you know the pain: linting a 200-file dbt project takes minutes in CI. For teams writing ANSI-compatible SQL, SQRust is a faster alternative.
Dialect support: SQRust supports ANSI, BigQuery, Snowflake, DuckDB, PostgreSQL, and MySQL. Set
dialectinsqrust.tomlor use the--dialectflag to enable dialect-aware parsing.
Two public corpora, all tools in ANSI mode, measured with hyperfine (5+ runs, Apple M-series, sqruff v0.34.1, sqlfluff v4.1.0):
22 files — jaffle-shop + attribution-playbook + mrr-playbook (real dbt projects):
| Tool | Time | ANSI rules |
|---|---|---|
| SQRust | 18 ms | 330 |
| sqruff | 37 ms | ~62 |
| sqlfluff 4.1.0 | 327 ms | ~89 |
2× faster than sqruff. 18× faster than sqlfluff.
500 files — Dune Spellbook (complex real-world analytics SQL):
| Tool | Time | ANSI rules |
|---|---|---|
| SQRust | 274 ms | 330 |
| sqruff | 394 ms | ~62 |
| sqlfluff 4.1.0 | 47,839 ms | ~89 |
1.4× faster than sqruff. 174× faster than sqlfluff.
Speed numbers are directly comparable — same corpus, same ANSI mode. Rule counts are not directly comparable: sqlfluff and sqruff rules cover 20+ dialects each; SQRust rules are ANSI-only today and include granular dialect-specific checks (e.g. separate rules for Oracle's SYSDATE, NVL2, DUAL table) that won't fire on most projects.
Homebrew (macOS):
brew install nafistiham/tap/sqrustOne-line installer (macOS / Linux — no Rust required):
curl -sSL https://raw.githubusercontent.com/nafistiham/SQRust/main/install.sh | shPre-built binary (manual):
# macOS (Apple Silicon)
curl -sSL https://github.com/nafistiham/SQRust/releases/latest/download/sqrust-aarch64-apple-darwin.tar.gz | tar -xz
sudo mv sqrust /usr/local/bin/
# macOS (Intel)
curl -sSL https://github.com/nafistiham/SQRust/releases/latest/download/sqrust-x86_64-apple-darwin.tar.gz | tar -xz
sudo mv sqrust /usr/local/bin/
# Linux (x86_64)
curl -sSL https://github.com/nafistiham/SQRust/releases/latest/download/sqrust-x86_64-unknown-linux-gnu.tar.gz | tar -xz
sudo mv sqrust /usr/local/bin/For Rust developers:
cargo install sqrust-cliBuild from source:
git clone https://github.com/nafistiham/SQRust.git
cd SQRust
cargo build -p sqrust-cli --release
# binary at: target/release/sqrust# Lint a directory
sqrust check models/
# Lint a single file
sqrust check query.sql
# JSON output (for CI integration)
sqrust check models/ --format json
# Auto-fix layout issues
sqrust fmt models/
# List all rules with enabled/disabled status
sqrust rules
# Enable or disable a specific rule
sqrust rules --disable Convention/SelectStar
sqrust rules --enable Convention/SelectStarOutput:
models/orders.sql:12:5: [Convention/SelectStar] Avoid SELECT *; list columns explicitly
models/orders.sql:34:1: [Layout/TrailingWhitespace] Trailing whitespace on line
models/payments.sql:8:24: [Convention/ColonCast] Avoid PostgreSQL-style ::cast; use CAST() instead
models/payments.sql:41:1: [Layout/LongLines] Line exceeds 120 characters (was 143)
Auto-fix (sqrust fmt):
Fixes Layout violations automatically — trailing whitespace, trailing newlines, excess blank lines. Convention, Lint, Structure, and Ambiguous rules are report-only; full auto-fix is on the roadmap.
$ sqrust fmt models/
Fixed: models/orders.sql
Fixed: models/payments.sql
Dialect support:
Set dialect in sqrust.toml, or pass --dialect on the command line:
[sqrust]
dialect = "bigquery" # ansi (default) | bigquery | snowflake | duckdb | postgres | mysql# Override per-run without editing sqrust.toml
sqrust check --dialect bigquery models/
sqrust fmt --dialect snowflake models/Supported values: ansi, bigquery, snowflake, duckdb, postgres, postgresql, mysql. Unknown values exit with a clear error.
VS Code extension:
Install from the VS Code Marketplace or search for SQRust in the Extensions panel.
- Lint on save and open — violations appear in the Problems panel
SQRust: Check FileandSQRust: Check Workspacecommands- Configure via settings:
sqrust.executablePath— path to binary (default:sqruston PATH)sqrust.dialect— override dialect per workspacesqrust.enabled— enable/disable linting
GitHub Actions:
- name: Lint SQL
run: |
curl -sSL https://raw.githubusercontent.com/nafistiham/SQRust/main/install.sh | sh
sqrust check models/330 rules across 6 categories, mapped to sqlfluff's catalog where applicable.
| Category | Rules | Examples |
|---|---|---|
| Convention | 69 | SelectStar, ColonCast, NotEqual, IsNull, NoIsnullFunction, NoDualTable, NoNvl2 |
| Layout | 66 | LongLines, TrailingWhitespace, ClauseOnNewLine, GroupByOnNewLine, OrderByOnNewLine |
| Lint | 63 | UnusedCte, DuplicateCteNames, DuplicateJoin, SelectWithoutFrom, AddColumnWithoutDefault |
| Structure | 63 | WildcardInUnion, NaturalJoin, MaxSelectColumns, LateralJoin, WindowFrameFullPartition |
| Ambiguous | 65 | FloatingPointComparison, CastWithoutLength, UnsafeDivision, ConvertFunction |
| Capitalisation | 4 | Keywords, Functions, Literals, Types |
Full rule list → docs/rules.md · Migration from sqlfluff · Architecture · Changelog
| SQRust | sqruff | sqlfluff | |
|---|---|---|---|
| Language | Rust | Rust | Python |
| Rules (ANSI mode)¹ | 330 | ~62 | ~89 |
| Speed (22 dbt files, ANSI) | 18 ms | 37 ms | 327 ms |
| Single binary | ✅ | ✅ | ❌ |
| Auto-fix | Partial (layout) | ✅ | ✅ |
| Config file | ✅ | ✅ | ✅ |
| Rule browser CLI | ✅ | ❌ | ❌ |
| Dialect support | ANSI, BigQuery, Snowflake, DuckDB, Postgres, MySQL | ANSI+ | 20+ dialects |
| dbt-ready | ✅ (BigQuery, Snowflake, ANSI) | ✅ | ✅ |
¹ Rule counts are not directly comparable across tools. sqlfluff and sqruff rules each apply across many dialects; SQRust's 330 rules are ANSI-only and include granular checks that competitors may combine into fewer, broader rules.
Create a sqrust.toml in your project root. sqrust automatically finds it by walking up from the path you lint — no flags needed:
[sqrust]
exclude = ["dbt_packages/**", "target/**"]
[rules]
disable = [
"Convention/SelectStar",
"Layout/LongLines",
]All 330 rules are enabled by default. Use disable to turn off specific rules by name, or use sqrust rules --disable <rule> to have it written automatically.
See sqrust.toml.example for a fully annotated template.
v0.2.0 (planned): Ruff-style allowlist — opt into rule categories with
select = ["Convention"]instead of opting out. Fields are reserved; using them now gives a clear error.
# .pre-commit-config.yaml
repos:
- repo: https://github.com/nafistiham/SQRust
rev: v0.1.4
hooks:
- id: sqrust
args: [check]curl -sSL https://raw.githubusercontent.com/nafistiham/SQRust/main/bench/benchmark.sh | bashOr clone and run:
git clone https://github.com/nafistiham/SQRust
cd SQRust/bench
./benchmark.sh # uses jaffle-shop as corpus
./benchmark.sh /your/dbt/project # or point at your own projectRequires: hyperfine, sqlfluff, sqruff, sqrust on PATH.
git clone https://github.com/nafistiham/SQRust
cd SQRust
cargo test --workspace # all tests must passEach rule lives in sqrust-rules/src/<category>/<rule_name>.rs with a test file in sqrust-rules/tests/.
Every rule has ≥13 tests. We use TDD — tests first.
Active personal project. I use SQRust on my own dbt projects and maintain it actively. v0.1.x is production-ready for ANSI SQL and supports BigQuery, Snowflake, DuckDB, PostgreSQL, and MySQL parsing via the --dialect flag. Dialect-specific lint rules are on the v0.2 roadmap.
Issues and PRs are welcome. If a rule fires incorrectly on your SQL, or you need a rule that isn't here, open an issue.
MIT
