Quickstart
Install sqltgen, write a schema and a couple of annotated queries, configure your target language, and run the generator. This walkthrough uses PostgreSQL and Rust — swap in any dialect or language you like.
The quickest way — no install required:
$ docker run --rm -v $(pwd):/workspace sqltgen/sqltgen generate --config sqltgen.json
Or build from source with Rust:
$ git clone https://github.com/sqltgen/sqltgen $ cd sqltgen/sqltgen $ cargo build --release
See the installation guide for all options including Homebrew and pre-built binaries.
Create a schema.sql file (or a migrations/ directory of
numbered files). sqltgen reads DDL to infer column types for your generated code.
-- schema.sql CREATE TABLE users ( id bigserial PRIMARY KEY, name text NOT NULL, email text NOT NULL UNIQUE, bio text, created_at timestamptz NOT NULL DEFAULT now() );
sqltgen supports CREATE TABLE, ALTER TABLE,
DROP TABLE, CREATE VIEW, and migration directories.
Column types are mapped to idiomatic language types automatically.
Add a -- name: FunctionName :command comment above each SQL
statement. Use @param_name for parameters — sqltgen infers
their types from the schema and rewrites them to the correct dialect
placeholder ($1, ?1, etc.).
-- queries.sql -- name: CreateUser :one INSERT INTO users (name, email) VALUES (@name, @email) RETURNING *; -- name: GetUser :one SELECT id, name, email, bio, created_at FROM users WHERE id = @id; -- name: ListUsers :many SELECT id, name, email, bio, created_at FROM users ORDER BY name; -- name: UpdateBio :one -- @bio null UPDATE users SET bio = @bio WHERE id = @id RETURNING id, name, bio; -- name: DeleteUser :exec DELETE FROM users WHERE id = @id;
Available commands:
| Command | Returns | Rust example | Java example |
|---|---|---|---|
:one |
Single optional row | Option<T> | Optional<T> |
:many |
All rows | Vec<T> | List<T> |
:exec |
Nothing | () | void |
:execrows |
Affected-row count | u64 | long |
Create a sqltgen.json file in your project root. Point it at
your schema and queries, and configure one or more output languages.
{
"version": "1",
"engine": "postgresql",
"schema": "schema.sql",
"queries": "queries.sql",
"gen": {
"rust": { "out": "src/db" }
}
}
The "engine" field accepts "postgresql",
"sqlite", or "mysql".
You can add multiple languages to the "gen" object and
sqltgen will emit code for all of them in one run.
// Generate Rust, Java, and TypeScript in one pass: "gen": { "rust": { "out": "src/db" }, "java": { "out": "gen", "package": "com.example.db" }, "typescript": { "out": "src/db" } }
Run sqltgen generate from your project root.
It reads sqltgen.json by default, or pass an explicit path with
--config.
$ sqltgen generate Generated src/db/users.rs Generated src/db/queries.rs Generated src/db/querier.rs Generated src/db/_sqltgen.rs Generated src/db/mod.rs
Import the generated module and call the typed query functions directly,
or use the Querier wrapper that holds your connection pool.
// main.rs use db::querier::Querier; use db::queries::{get_user, create_user}; let q = Querier::new(pool.clone()); // Via the Querier wrapper let user = q.get_user(42).await?; // Or call the free function directly let new_user = create_user( &pool, "Alice", "alice@example.com" ).await?;
The Querier struct is the primary API for query execution —
it owns a reference to your connection pool and delegates to the
generated free functions.
All generated functions are async (in Rust), typed to your exact schema,
and have no hidden runtime overhead.
This covered the basics. The full documentation goes deeper:
RETURNING, CTEs, JOINs
sqltgen.json options, type overrides, query grouping