Getting Started
This guide will walk you through installing SQG and generating your first type-safe database access code.
Prerequisites
Section titled “Prerequisites”Before you begin, ensure you have:
- Node.js 18 or later
- pnpm (recommended) or npm/yarn
Installation
Section titled “Installation”Global installation (recommended)
Section titled “Global installation (recommended)”# pnpm (recommended)pnpm add -g @sqg/sqgpnpm approve-builds -g # needed for native dependencies
# npmnpm install -g @sqg/sqg
# yarnyarn global add @sqg/sqgProject-local installation
Section titled “Project-local installation”# pnpmpnpm add -D @sqg/sqg
# npmnpm install --save-dev @sqg/sqg
# yarnyarn add -D @sqg/sqgFrom source
Section titled “From source”git clone https://github.com/sqg-dev/sqg.gitcd sqg/sqgpnpm installpnpm buildpnpm link --globalQuick Start
Section titled “Quick Start”Option A: Initialize a New Project (Recommended)
Section titled “Option A: Initialize a New Project (Recommended)”The fastest way to get started is using the sqg init command:
# Create a new project with TypeScript + SQLite (default)sqg init
# Or specify a different generatorsqg init --generator typescript/duckdb
# Java targetssqg init --generator java/sqlitesqg init --generator java/duckdbsqg init --generator java/duckdb/arrowsqg init --generator java/postgresThis creates:
sqg.yaml- Project configurationqueries.sql- Example SQL file with migrations and queries./generated/- Output directory for generated code
Then run:
sqg sqg.yamlOption B: Manual Setup
Section titled “Option B: Manual Setup”-
Create your SQL file
Create a file called
queries.sql:-- MIGRATE 1CREATE TABLE users (id INTEGER PRIMARY KEY,name TEXT NOT NULL,email TEXT UNIQUE);-- QUERY all_usersSELECT * FROM users;-- QUERY get_user :one@set id = 1SELECT * FROM users WHERE id = ${id};-- EXEC create_user@set name = 'John Doe'INSERT INTO users (name, email) VALUES (${name}, ${email});-- EXEC delete_user@set id = 1DELETE FROM users WHERE id = ${id}; -
Create a project configuration
Create a file called
sqg.yaml:version: 1name: my-appsql:- files:- queries.sqlgen:- generator: typescript/sqliteoutput: ./src/generated/ -
Run the generator
Terminal window sqg sqg.yamlThis creates
./src/generated/my-app.tswith fully typed query functions. -
Use the generated code
import Database from 'better-sqlite3';import { MyApp } from './generated/my-app';// Initialize databaseconst db = new Database('app.db');// Run migrationsfor (const migration of MyApp.getMigrations()) {db.exec(migration);}// Create query instanceconst queries = new MyApp(db);// Use typed queriesconst users = queries.allUsers();console.log(users);// [{ id: 1, name: 'Alice', email: '[email protected]' }, ...]const user = queries.getUser(1);console.log(user?.name); // 'Alice'
Project Configuration
Section titled “Project Configuration”The sqg.yaml file defines your project structure:
version: 1 # Config version (always 1)name: my-project # Project name (used for class names)
sql: - files: - queries.sql # SQL files to process - users.sql gen: - generator: typescript/sqlite output: ./src/db/
- generator: java/sqlite output: ./java/src/main/java/db/ config: package: com.myapp.dbAvailable Generators
Section titled “Available Generators”Generators follow the format <language>/<engine>[/<driver>]:
| Generator | Description | Documentation |
|---|---|---|
typescript/sqlite | TypeScript for SQLite (sync API) | TypeScript + SQLite |
typescript/duckdb | TypeScript for DuckDB (async API) | TypeScript + DuckDB |
java/sqlite | Java with JDBC for SQLite | Java + JDBC |
java/duckdb | Java with JDBC for DuckDB | Java + JDBC |
java/duckdb/arrow | Java with Arrow API (high-performance) | Java + DuckDB Arrow |
java/postgres | Java with JDBC for PostgreSQL | Java + JDBC |
See individual generator documentation for configuration options, type mappings, and usage examples.
Database Engines
Section titled “Database Engines”| Engine | Description | TypeScript | Java |
|---|---|---|---|
sqlite | Embedded, no server required | typescript/sqlite | java/sqlite |
duckdb | Analytics, complex types | typescript/duckdb | java/duckdb, java/duckdb/arrow |
postgres | Full-featured SQL server | — | java/postgres |
Notes:
- SQLite and DuckDB use in-memory databases for type introspection (no server needed)
- PostgreSQL requires a running server; set
SQG_POSTGRES_URLenvironment variable - See individual generator pages for installation and usage details
Development Workflow with DBeaver
Section titled “Development Workflow with DBeaver”SQG’s SQL syntax is designed to be compatible with DBeaver, the popular open-source database IDE. The @set variable syntax is a DBeaver feature, which means you can use DBeaver as your primary SQL development environment.
Why DBeaver?
Section titled “Why DBeaver?”DBeaver natively supports the @set variable syntax that SQG uses. This means you can:
- Execute queries with parameters directly in DBeaver
- Modify parameter values and re-run to test different scenarios
- Get autocomplete for table and column names
- View query execution plans for optimization
- Debug queries before generating code
Recommended Workflow
Section titled “Recommended Workflow”-
Install DBeaver (free, cross-platform)
-
Connect DBeaver to your database (SQLite file, DuckDB, or PostgreSQL server)
-
Create your SQL file with migrations and queries
-
Develop queries interactively in DBeaver:
- Run migrations to set up your schema
- Execute queries and verify results
- Modify
@setvalues to test edge cases
-
Run SQG to generate code when your queries are ready
Testing Parameters in DBeaver
Section titled “Testing Parameters in DBeaver”The @set declarations work as variable definitions in DBeaver. Modify parameter values and re-run queries to test different scenarios:
-- QUERY find_users@set name = 'Alice' -- Change this value in DBeaver to test@set min_age = 25 -- different scenariosSELECT * FROM users WHERE name = ${name} AND age >= ${min_age};Select the entire block (including @set lines) and execute - DBeaver will substitute the variables automatically.
SQL Syntax Overview
Section titled “SQL Syntax Overview”SQG uses comment annotations to define queries:
-- MIGRATE 1 -- Schema migrations (numbered)-- TESTDATA -- Test data for type introspection-- QUERY name -- Select queries (returns rows)-- QUERY name :one -- Returns single row or undefined-- QUERY name :pluck -- Returns array of first column values-- EXEC name -- Execute statements (INSERT/UPDATE/DELETE)Parameters use @set to define and ${name} to reference:
-- QUERY find_user :one@set id = 1SELECT * FROM users WHERE id = ${id};See SQL Syntax Reference for complete documentation including complex types, modifiers, and best practices.
CLI Reference
Section titled “CLI Reference”sqg <config-file> # Generate code from configsqg --validate <config> # Validate without generatingsqg --format json <config> # Output as JSONsqg init # Initialize new projectsqg syntax # Show SQL syntax referencesqg --help # Show helpSee the CLI Reference for complete documentation including all commands, options, JSON output format, and error codes.
Next Steps
Section titled “Next Steps”- Generators:
- TypeScript + SQLite - Sync API with better-sqlite3
- TypeScript + DuckDB - Async API with complex types
- Java + JDBC - Standard JDBC for any database
- Java + DuckDB Arrow - High-performance Arrow API
- SQL Syntax Reference - Complete annotation reference
- CLI Reference - Full command-line documentation
- Playground - Try SQG in your browser
- FAQ - Common questions and troubleshooting