What is ts-sql-query?¶
ts-sql-query is a type-safe SQL query builder for TypeScript. It allows you to write dynamic queries with full type safety โ meaning that the TypeScript compiler can validate your queries at compile time.
Type-safe SQL means that mistakes in your queries are caught at compile time. With ts-sql-query, you can safely refactor your database schema: any issues will be surfaced immediately by the compiler.
ts-sql-query is not an ORM โ it focuses on full SQL control with type safety.

Why?¶
There are many libraries available in JavaScript/TypeScript that allows querying a SQL database, but they are typically:
- ORMs often limit direct control over SQL and can obscure database capabilities.
- Many query builders rely on fragile string concatenation.
- Some libraries lack proper type-safety integration.
- Most tools make it hard to write truly dynamic SQL in a safe and expressive way.
ts-sql-query addresses these issues by providing a type-safe, SQL-centric API, with rich support for building dynamic queries in a declarative style.
For more details on the principles behind the library, see Philosophy and Design Goals.
Supported runtimes¶
ts-sql-query supports Node.js and Bun.
Supported Databases¶
ts-sql-query uses a unified dialect inspired by SQLite and PostgreSQL, with naming conventions adapted to JavaScript. It automatically generates the correct SQL for your target database.
Install¶
Install in Bun:
ts-sql-query is an ESM-only package and requires Node.js 22 or newer. The set of importable paths is enforced by the exports map in package.json; anything not declared there fails with ERR_PACKAGE_PATH_NOT_EXPORTED. TypeScript consumers must use moduleResolution: "node16", "nodenext" or "bundler".
Two ways to import:
-
Aggregated root entry for cross-database use:
Re-exports the cross-database surface (everything fromimport { Table, Values, CustomBooleanTypeAdapter, dynamicPick, extractColumnsFrom, type Connection, type SelectedRow } from 'ts-sql-query'Connection,Table,View,TypeAdapter,Values,TsSqlError,dynamicCondition,extras/types,extras/utilsandextras/sync). Database-specific symbols are intentionally not re-exported here. -
Per-feature subpaths for database-specific imports (each connection, each query runner,
IDEncrypter) โ for example:
The complete enumerated list of public subpaths lives in the exports field of package.json and in the project README. Abstract base classes, transaction utility runners, error mappers and the internals (internal/, expressions/, queryBuilders/, sqlBuilders/, utils/, complexProjections/) are deliberately not part of the public API.
Escape hatch
Anything not listed in the public API can still be imported through the ts-sql-query/__UNSUPPORTED__/<original/path> prefix as an explicit, opt-in escape hatch (for custom dialects, plugins or debugging). Paths under __UNSUPPORTED__/ carry no stability guarantees and may change, break or disappear in any release, including patch releases.
Related projects¶
- ts-sql-codegen: Utility that generates table mapper classes for
ts-sql-queryby inspecting a database through tbls.