Qubu
Build parameterized SQL from typed tables, expressions, and clauses.
Qubu builds SQL from values. Tables, expressions, clauses, and complete queries compose without a mutable query builder. TypeScript tracks selected row shapes, source scope, and nullability, while rendering returns SQL text and ordered parameters.
The preferred source style names each projected field and writes the final
select() clauses in SQL order. Clause values remain order-independent at
runtime, so a reusable where() or orderBy() fragment can be built earlier
and placed in that final call where it reads best.
Start here
If this is your first query, follow Getting started to
define a table, build a SELECT, and inspect its SQL and parameters.
Choose a task
- Build a
SELECTwith projections, joins, predicates, ordering, and grouping. - Compose queries with CTEs, derived tables, subqueries, and set operations.
- Compose SQL templates for trusted syntax with bound values and metadata-preserving fragment substitutions.
- Write mutations with typed
INSERT,UPDATE, andDELETEstatements. - Use Qubu tables with Drizzle while moving query call sites without duplicating schema declarations.
- Use Qubu with Better Auth with plugin-aware schema derivation and a native transactional database adapter.
- Extend Qubu with a custom source, clause, dialect policy, or typed expression.
- Read JSON scalars from structured JSON paths.
- Enable the Vite compiler hint when query modules should opt into named imports through a directive.
- Inspect an existing database through the optional user-owned catalog boundary.
- Generate a schema module from one complete, non-lossy Snapshot v1 introspection result.
- Compare snapshots with explicit rename hints and reviewable safety diagnostics.
- Build migration plans as reviewed, deterministic data before DDL emission.
- Emit DDL from an approved migration plan without handing Qubu a database connection.
- Operate migrations with versioned artifacts, verified adapter profiles, baselines, a portable executor, and explicit recovery.
The query pipeline
The same query value can be rendered for inspection or passed to an adapter for execution. The application-owned adapter handles the driver, database connection, and driver-specific row and mutation-result details.
Values become bound parameters, and the active dialect quotes identifiers. Raw SQL is available through explicit unsafe helpers. The call site shows where that unchecked syntax enters the query.
Understand the Qubu model
Use these pages when a guide leaves a rule unexplained or when an extension needs to preserve a fact across composition:
| Model | Start with | Covers |
|---|---|---|
| Query model | Source scope | Source identity, result shapes, fragments, metadata, and query composition |
| Schema model | Tables and names | Tables, snapshots, diffs, migration plans, and DDL emission |
| Migration operations | Migration operations | Artifacts, adapters, CLI policy, baselines, execution, and recovery |
| Database introspection | Database introspection | Catalog readers, Snapshot v1 mapping, identities, diagnostics, and support limits |
| Schema source generation | Generate a schema | Machine-owned TypeScript, identity handoff, controlled mappings, and v1 exclusions |
| Rendering and execution | Dialects and execution | Placeholder and identifier policies, capabilities, adapters, and raw-SQL boundaries |
| SQL semantic types | SQL semantic types | Application types, SQL domains, nullability, and compatible operations |
A small example
import { eq, from, integer, render, select, table, text, where } from "qubu"
const users = table("users", {
id: integer(),
name: text(),
})
const query = select({ id: users.id, name: users.name }, from(users), where(eq(users.id, 7)))
render(query)
// {
// text: 'SELECT "users"."id" AS "id", "users"."name" AS "name" FROM "users" WHERE ("users"."id" = ?)',
// parameters: [7],
// }
The inferred row is { id: number; name: string }. The value 7 stays out
of the SQL text and appears in the parameters array in placeholder order.
The supported features page is the canonical package-entrypoint and ownership map. Applications may use Qubu's portable migration executor while retaining credentials, approval policy, custom SQL, and deployment lifecycle ownership. Troubleshooting starts from common errors and points to the concept page behind each one.