syntaqlite 0.0.7

Parser, formatter, validator, and language server for SQLite SQL — built on SQLite's own grammar
Documentation
# <img src="web/docs/static/favicon.svg" width="32" height="32" alt="">&nbsp;&nbsp;syntaqlite

[![CI](https://github.com/LalitMaganti/syntaqlite/actions/workflows/ci.yml/badge.svg)](https://github.com/LalitMaganti/syntaqlite/actions/workflows/ci.yml)
[![Crates.io](https://img.shields.io/crates/v/syntaqlite)](https://crates.io/crates/syntaqlite)
[![VS Code](https://img.shields.io/visual-studio-marketplace/v/syntaqlite.syntaqlite)](https://marketplace.visualstudio.com/items?itemName=syntaqlite.syntaqlite)

A parser, formatter, validator, and language server for SQLite SQL, built on SQLite's own grammar and tokenizer. If SQLite accepts it, syntaqlite parses it. If SQLite rejects it, so does syntaqlite.

**[Docs](https://docs.syntaqlite.com)** · **[Playground](https://playground.syntaqlite.com)** · **[VS Code Extension](https://marketplace.visualstudio.com/items?itemName=syntaqlite.syntaqlite)** · **[MCP Server](integrations/mcp/README.md)**

> **Note:** syntaqlite is at 0.x — APIs and CLI flags may change before 1.0.

## Why syntaqlite

Most SQL tools parse a subset of SQL, invent their own grammar, or handle SQLite as an afterthought. syntaqlite uses SQLite's own Lemon-generated grammar and tokenizer, compiled from C — the parser doesn't approximate SQLite, it _is_ SQLite's grammar compiled into a reusable library.

SQLite isn't one fixed language — syntax changes between releases, and compile-time flags enable optional features. syntaqlite tracks this across all tools:

```bash
syntaqlite --sqlite-version 3.32.0 validate \
  -e "DELETE FROM users WHERE id = 1 RETURNING *;"
```
```text
error: syntax error near 'RETURNING'
 --> <stdin>:1:32
  |
1 | DELETE FROM users WHERE id = 1 RETURNING *;
  |                                ^~~~~~~~~
```

`RETURNING` was added in SQLite 3.35.0 — Android 13 still ships SQLite 3.32.2.

We've tested against ~396K statements from [SQLite's upstream test suite](https://sqlite.org/testing.html) with ~99.7% agreement on parse acceptance. See the [detailed comparison](https://docs.syntaqlite.com/main/reference/comparison/) for how syntaqlite stacks up against other tools.

## What it does

### Validate — catch errors without a database

Finds unknown tables, columns, and functions against your schema — the same errors `sqlite3_prepare` would catch, but without needing a database. Unlike `sqlite3`, syntaqlite finds **all** errors in one pass:

```sql
CREATE TABLE orders (id, status, total, created_at);

WITH
  monthly_stats(month, revenue, order_count) AS (
    SELECT strftime('%Y-%m', o.created_at), SUM(o.total)
    FROM orders o WHERE o.status = 'completed'
    GROUP BY strftime('%Y-%m', o.created_at)
  )
SELECT ms.month, ms.revenue, ms.order_count,
  ROUDN(ms.revenue / ms.order_count, 2) AS avg_order
FROM monthly_stats ms;
```

**sqlite3** stops at the first error and misses the function typo entirely:
```text
Error: in prepare, table monthly_stats has 2 values for 3 columns
```

**syntaqlite** finds both — CTE column count mismatch and the `ROUDN` typo — with source locations and suggestions:
```text
error: table 'monthly_stats' has 2 values for 3 columns
  |
2 | monthly_stats(month, revenue,
  | ^~~~~~~~~~~~~

warning: unknown function 'ROUDN'
   |
14 | ROUDN(ms.revenue / ms.order_count,
   | ^~~~~
   = help: did you mean 'round'?
```

### Format

Deterministic formatting with configurable line width, keyword casing, and indentation:

```bash
echo "select u.id,u.name, p.title from users u join posts p on u.id=p.user_id
where u.active=1 and p.published=true order by p.created_at desc limit 10" \
  | syntaqlite fmt
```
```sql
SELECT u.id, u.name, p.title
FROM users u
  JOIN posts p ON u.id = p.user_id
WHERE u.active = 1
  AND p.published = true
ORDER BY p.created_at DESC
LIMIT 10;
```

### Version and compile-flag aware

SQLite isn't one fixed language — syntax changes between releases, and [compile-time flags](https://www.sqlite.org/compile.html) enable optional features. syntaqlite tracks this across all tools:

```bash
# Reject syntax your target SQLite version doesn't support
syntaqlite --sqlite-version 3.32.0 validate query.sql

# Enable optional syntax from compile-time flags
syntaqlite --sqlite-cflag SQLITE_ENABLE_MATH_FUNCTIONS validate query.sql
```

### Validate SQL inside other languages *(experimental)*

SQL lives inside Python and TypeScript strings in most real codebases. syntaqlite extracts and validates it, handling interpolation holes:

```python
# app.py
def get_user_stats(user_id: int):
    return conn.execute(
        f"SELECT nme, ROUDN(score, 2) FROM users WHERE id = {user_id}"
    )
```
```bash
syntaqlite validate --experimental-lang python app.py
```
```text
warning: unknown function 'ROUDN'
 --> app.py:3:23
  |
3 |         f"SELECT nme, ROUDN(score, 2) FROM users WHERE id = {user_id}"
  |                       ^~~~~
  = help: did you mean 'round'?
```

### Editor integration

Full language server — no database connection required. Diagnostics, format on save, completions, and semantic highlighting.

**VS Code** — install the [syntaqlite extension](https://marketplace.visualstudio.com/items?itemName=syntaqlite.syntaqlite) from the marketplace.

**Claude Code** — `syntaqlite plugin install` · **Claude Desktop / Cursor** — `pip install syntaqlite-mcp` ([docs](integrations/mcp/README.md))

**Any editor with LSP support:**

```bash
syntaqlite lsp
```

### Parse

Full abstract syntax tree with side tables for tokens, comments, and whitespace — for code generation, migration tooling, or static analysis.

```bash
syntaqlite parse -e "SELECT 1 + 2" --output text
```

## Install

**Homebrew**

```bash
brew install LalitMaganti/tap/syntaqlite
```

**Shell (macOS / Linux)**

```bash
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/LalitMaganti/syntaqlite/releases/latest/download/syntaqlite-cli-installer.sh | sh
```

**PowerShell (Windows)**

```powershell
powershell -ExecutionPolicy ByPass -c "irm https://github.com/LalitMaganti/syntaqlite/releases/latest/download/syntaqlite-cli-installer.ps1 | iex"
```

**Cargo**

```bash
cargo install syntaqlite-cli
```

## Use as a library

**Rust**

```toml
[dependencies]
syntaqlite = { version = "0.0.7", features = ["fmt"] }
```

**JavaScript / WASM**

```bash
npm install @syntaqlite/js
```

**C** — the parser, tokenizer, formatter, and validator all have C APIs. See the [C API docs](https://docs.syntaqlite.com/reference/c-api/) for details.

## Architecture

The parser and tokenizer are written in C, directly wrapping SQLite's own grammar. Everything else — formatter, validator, LSP — is written in Rust with C bindings available.

The split is intentional. The C parser is as portable as SQLite itself: it can run inside database engines, embedded systems, or anywhere SQLite runs. The Rust layer moves fast for developer tooling where the standard library and the crate ecosystem matter.

## Building from source

```bash
tools/install-build-deps
tools/cargo build
```

## Contributing

See the [contributing guide](https://docs.syntaqlite.com/contributing/) for architecture overview and testing instructions.

## License

Apache 2.0. SQLite components are public domain under the [SQLite blessing](https://www.sqlite.org/copyright.html). See [LICENSE](LICENSE) for details.