syntaqlite-cli 0.5.9

Fast, accurate SQLite SQL formatter, validator, and language server — built on SQLite's own grammar
Documentation

syntaqlite-cli

The syntaqlite command-line tool: format, validate, and parse SQLite SQL, with a bundled language server.

Docs · Playground · GitHub

Install

cargo install syntaqlite-cli

Other install methods (Homebrew, mise, pip, standalone download) are listed in the top-level README.

Usage

Format

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
SELECT u.id, u.name, p.title
FROM users AS u
JOIN posts AS p ON u.id = p.user_id
WHERE
  u.active = 1
  AND p.published = true
ORDER BY
  p.created_at DESC
LIMIT 10;

Also works on files and globs:

syntaqlite fmt 'migrations/**/*.sql'

Validate

Check SQL against a schema without touching a database:

syntaqlite analyze --schema schema.sql -e "SELECT nme FROM users"
error: unknown column 'nme'
 --> <expression>:1:8
  |
1 | SELECT nme FROM users
  |        ^~~
  = help: did you mean 'name'?

Pin to a specific SQLite version to catch syntax that won't run on your target:

syntaqlite --sqlite-version 3.32.0 validate -e "DELETE FROM users RETURNING *;"

Parse

syntaqlite parse -e "SELECT 1 + 2"
SelectStmt
  columns:
    ResultColumnList [1 items]
      ResultColumn
        expr:
          BinaryExpr
            op: PLUS
            left:  Literal { literal_type: INTEGER, source: "1" }
            right: Literal { literal_type: INTEGER, source: "2" }

Language server

syntaqlite lsp

Point your editor's LSP client at this command for diagnostics, completions, and format-on-save. See editor integration for setup.

See the CLI reference for the full list of subcommands and flags, and project configuration for using syntaqlite.toml to set schemas and formatting options per project.

Advanced: building a custom CLI wrapper

The crate also exposes a CliApp trait so downstream projects can ship their own syntaqlite-style binary with a pre-baked dialect, avoiding the runtime --dialect flag and shared-library plumbing. This is the right choice when your project has a custom SQLite dialect (extra tables, functions, or grammar) and you want end users to get the same UX as the stock syntaqlite binary without learning about dialect loading.

[dependencies]
syntaqlite-cli = { version = "0.4.2", default-features = false }
use syntaqlite_cli::{CliApp, run};
use syntaqlite::any::AnyDialect;

struct MyCli;

impl CliApp for MyCli {
    fn name(&self) -> &str { "my-sql-cli" }
    fn about(&self) -> &str { "SQL tools for MyProject's dialect" }
    fn default_dialect(&self) -> Option<AnyDialect> {
        Some(my_dialect().into())
    }
}

fn main() {
    run(&MyCli);
}

See examples/cli_wrapper.rs for a runnable example.

Features

Feature Default Description
bundled-sqlite-dialect Yes Bake in the SQLite dialect and ship the default syntaqlite binary
dynload Yes Expose --dialect / --dialect-name flags for loading dialects from shared libraries
codegen Yes Expose dialect / dialect-tool subcommands for generating dialect sources
mcp Yes Expose the mcp subcommand

Wrappers that bake in a single dialect typically disable bundled-sqlite-dialect, dynload, and codegen to keep the surface area small.

License

Apache 2.0. SQLite components are public domain under the SQLite blessing.