Introducing SQG
We’re excited to announce SQG (SQL Query Generator), a tool that generates type-safe database access code from your SQL queries.
The Problem
Section titled “The Problem”Writing database code means maintaining SQL queries and matching TypeScript/Java types. When schemas change, you update both—and hope nothing breaks. ORMs abstract SQL away, but what if you want to write SQL directly while keeping type safety?
The Solution
Section titled “The Solution”SQG reads annotated .sql files, executes queries against real databases to introspect column types, and generates fully-typed wrapper code.
Write your SQL with simple annotations:
-- MIGRATE createUsersTableCREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL, email TEXT);
-- QUERY getUserById :one@set id = 1SELECT id, name, email FROM users WHERE id = ${id};
-- QUERY getUsersSELECT id, name, email FROM users;
-- EXEC insertUser@set name = 'John'INSERT INTO users (name, email) VALUES (${name}, ${email});SQG generates type-safe code:
export class Queries { getUserById(id: number): { id: number; name: string; email: string | null } | undefined getUsers(): { id: number; name: string; email: string | null }[] insertUser(name: string, email: string): RunResult}Key Features
Section titled “Key Features”- Type-safe by design - Column types inferred from your actual database
- Multiple databases - SQLite, DuckDB, and PostgreSQL
- Multiple languages - Generate TypeScript or Java from the same SQL
- DBeaver compatible - Develop queries in DBeaver, generate code from the same file
- Zero runtime overhead - Generated code is plain function calls
Get Started
Section titled “Get Started”Install SQG:
pnpm add -g @sqg/sqgpnpm approve-builds -g # needed for sqlite dependencyCreate a sqg.yaml config and your SQL file, then run sqg sqg.yaml. Check out the Getting Started guide for details.
We’d love your feedback! File issues and feature requests on GitHub.