drizzle-plus

Add focused query-builder extensions and SQL helpers to Drizzle ORM without changing the way you already model tables or execute queries.

drizzle-plus fills a few practical gaps around Drizzle's relational query builder. Its extensions add methods such as count() and updateMany(); its SQL helpers make common expressions and dialect-specific functions easier to compose with TypeScript.

The package supports PostgreSQL, MySQL, and SQLite. Most query extensions are enabled with a dialect-specific import, while shared SQL helpers come from the root package.

Start here

  • Getting started — install the package, enable an extension, and choose the right import path.
  • Create rows — insert one or more rows with typed results.
  • Upsert rows — insert or update rows based on a primary key or unique constraint.
  • Build a paginated query — derive the next-page filter from a cursor and sort order.
  • Compose a selection — build reusable, type-checked findMany configs.

Features

Query extensions

These methods extend db.query.<table>. Each page includes the import that activates the method and the behavior to check before using it.

Feature Use it when
Create You need an insert operation with optional duplicate skipping.
Upsert A conflict should update an existing row.
Update many One update should affect multiple rows, optionally with a limit.
Count You need a filtered row count.
Find unique The filter identifies one row through a unique key.
Find many and count A list screen needs both page data and the total count.
Cursor pagination You need stable pagination without hand-writing cursor filters.
Query composition You want to reuse and merge findMany options without executing them.

Database and select helpers

These helpers extend db, tables, or the select builder.

Feature Use it when
$select A plain object should become a typed db.select() selection.
$values A small in-memory row set should become a SQL VALUES relation or CTE.
Aliases A select or relational query needs to be used as a named subquery.
Recursive CTEs A query needs to refer to its own result while it is being built.
Materialized CTEs PostgreSQL should materialize or inline a CTE explicitly.
$without A table's column selection should omit a few fields.
fromSingle() Optional joins must still produce one placeholder row.
withoutFrom() A select should contain expressions but no FROM clause.

SQL building blocks

Feature Use it when
caseWhen() A conditional SQL expression should remain type-aware.
nest() A one-column query should become a scalar SQL expression.
toSQL() A JavaScript value should be safely bound as SQL input.
Universal SQL functions You need common numeric, text, date, or null-handling functions.
Dialect-specific functions A database-specific JSON, UUID, cast, or string function is required.
Timestamps A database-generated date or timestamp should decode as a JavaScript Date.

Utilities and types

Feature Use it when
orThrow() An empty query result should become an exception.
Merge query options Reusable filters and selections need a type-safe merge.
toSelection() A reusable plain object should become a select selection.
Types A helper type should be derived from an existing relational query builder.