Skip to content

Write SQL. Read TypeScript. ​

typed-sql analyzes static SQL against your schema. Keep your application-owned driver and SQL architecture—without adopting an ORM or model layer.

Get startedSee how it worksView on GitHub

Stable compiler path. Exact editor hovers use optional experimental tooling.

ts
import { sql } from "@typed-sql/postgres";

export const accountById = (accountId: bigint) => sql`
  SELECT account.id, account.email, account.status
  FROM users AS account
  WHERE account.id = ${accountId}
`;

Checked against the maintained PostgreSQL example schema. The compiler proves a row contract and an ordered parameter tuple; it does not validate rows at runtime unless you add a validator.

Try it in your browser ​

Edit the query and hover a binding, adapter result, or indexed row to inspect its inferred type. Switch grammars above; the shared schema workspace supplies the evidence for every live example on the site.

main.ts
Hover accountById for its type

SQL in, exact contract out ​

The selected grammar resolves SQL syntax, names, database types, nullability, and parameter positions. Supported static SQL receives an exact contract. Missing evidence remains unknown; invalid, ambiguous, or deliberately unsupported SQL produces a diagnostic instead of a guessed type.

  1. Database schema
  2. Schema snapshot
  3. SQL template
  4. Compiler check
  5. Driver execution

Values remain parameters throughout this path. In the hero query, accountId renders as PostgreSQL placeholder $1; the runtime value never becomes SQL text. Read the inference and safety boundary.

Keep your database stack ​

A grammar package owns SQL analysis, not connections. typed-sql does not install a driver, create a hidden pool, own migrations, or introduce a model layer. Choose the integration boundary that fits the application you already have.

Composition stays explicit ​

Ordinary interpolations always become parameters. SQL structure requires a visible API, so code review can distinguish data from syntax: sql.fragment for static structure, sql.empty for no structure, sql.ident() for quoted identifiers, and trusted sql.raw() for an explicit escape hatch. See conditional and repeated composition.

ts
const query = sql`
  SELECT id, email
  FROM users
  ${includeSuspended ? sql.empty : sql.fragment`WHERE status = ${"active"}`}
`;

Choose your level of adoption ​

Start with compile-time checking, then add runtime and operational layers only where they solve an application problem.

PostgreSQL, MySQL, and SQLite ​

Each stable grammar owns its language semantics, built-ins, coercions, nullability rules, version gates, and diagnostics. A supported range is distinct from the exact versions exercised by the repository.

Stable

PostgreSQL

PostgreSQL 14–18 grammar and catalog provider, with an optional adapter for an application-owned pg pool.

PostgreSQL support
Stable

MySQL

MySQL 8.4 and 9.7 LTS grammar and catalog provider, with an optional adapter for mysql2.

MySQL support
Stable

SQLite

SQLite 3.39.0–3.53.4 grammar and PRAGMA catalog provider, with an optional node:sqlite adapter.

SQLite support

Compare supported and exactly tested versions or inspect the generated grammar support matrix.

Compared with alternatives ​

typed-sql fits SQL-first teams that want schema-aware static contracts without moving database design or connection ownership into a new model layer. Other approaches remain better fits for different jobs.

CapabilityRaw drivertyped-sqlQuery builderFull ORM
SQL remains the primary interfaceYesYesVariesUsually not
Schema-aware static row inferenceNoSupported static SQLLibrary-dependentModel/query-dependent
Runtime driver includedYesNoVariesUsually
Dynamic programmatic compositionApplication codeExplicit fragmentsCore strengthFramework-dependent
Relations and unit of workNoNoLimited or variesCore strength
Migrations includedNoNoLibrary-dependentCommonly

Understand typed-sql's package and ownership boundaries.

Production controls when needed ​

The compiler requires a schema snapshot and an authoritative check. Everything below is an optional, composable control rather than a prerequisite for the first query.

Choose controls by operational concern.

Evidence and maturity ​

Stable packages

Compiler and database path

Core contracts, schema/configuration, compiler, CLI, PostgreSQL, MySQL, SQLite, conformance, and OpenTelemetry integration follow the stable package contract.

  • core
  • opentelemetry
  • ast
  • schema
  • config
  • compiler
  • conformance
  • postgres
  • mysql
  • sqlite
  • cli
Experimental tooling

Rich editor integration

The TypeScript preview bridge, language server, and editor distributions remain experimental. The stable CLI/compiler check is authoritative.

  • ts-bridge
  • language-server

The repository exercises real database versions, packed consumers, soundness and coverage checks, and explicit performance budgets. Performance figures are regression guardrails for documented fixtures—not promises about database latency or application throughput. Review the workloads, budgets, and reproducible comparison method.

Start with your database ​

Choose a dialect for the shortest path from schema evidence to a checked query, or begin with a complete maintained application.

Released under the MIT License.