# better-drizzle > Minimal, type-safe repository helpers for Drizzle ORM. better-drizzle wraps an existing Drizzle client and gives every table a small, typed API (findMany, create, upsert, paginate, cursor, include, transactions, hooks, plugins) without hiding Drizzle or rebuilding an ORM. - Latest release: 0.3.0 (some pages document unreleased APIs marked "Added in "; check the version in the project's package.json and the changelog before using them). - Requires `drizzle-orm` >=1.0.0-rc.4 <1.0.0-rc.5 (Drizzle ORM 1.x with `defineRelations`). Projects on drizzle-orm 0.x must use better-drizzle 0.2.x. - Databases: PostgreSQL, MySQL, SQLite. - Install: `npm install better-drizzle drizzle-orm@1.0.0-rc.4` - Setup: `const db = better(drizzle({ client, relations }))`, then `db..findMany(...)`. Raw Drizzle stays available. - Official plugins are subpath exports of the same package: `better-drizzle/ata`, `better-drizzle/auth`, `better-drizzle/cache`, `better-drizzle/cache/redis`, `better-drizzle/eslint`, `better-drizzle/plugins`, `better-drizzle/rules`, `better-drizzle/soft-delete`, `better-drizzle/tenant`, `better-drizzle/timestamps`, `better-drizzle/uuid`, `better-drizzle/uuid/mysql`, `better-drizzle/uuid/sqlite`, `better-drizzle/zod`. There are no separate `@better-drizzle/*` packages. - Every page is available as Markdown by appending `.md` to its URL. - Full docs in one file: https://better-drizzle.com/llms-full.txt - Changelog: https://better-drizzle.com/changelog.md - Agent skill: `npx skills add almeidazs/better-drizzle` ## Start here - [Introduction](https://better-drizzle.com/docs.md): Minimal, type-safe repository helpers for Drizzle ORM - keep the type-safety, drop the repetitive query glue. - [Getting started](https://better-drizzle.com/docs/getting-started.md): Install better-drizzle, define a Drizzle schema, create the client, and run your first typed queries. - [Why better-drizzle?](https://better-drizzle.com/docs/why.md): What you gain over raw Drizzle, what stays exactly the same, and the few cases where raw Drizzle is still the right tool. - [better-drizzle vs Drizzle](https://better-drizzle.com/docs/compare/drizzle.md): What the wrapper adds on top of raw Drizzle, what it costs, and when raw Drizzle is still the better tool. - [better-drizzle vs Prisma](https://better-drizzle.com/docs/compare/prisma.md): A Prisma-style API on top of Drizzle. How the calls map, what is different, and what Prisma has that better-drizzle does not. - [Migrating from raw Drizzle](https://better-drizzle.com/docs/guides/migrating-from-drizzle.md): A practical path from hand-written Drizzle query glue to better-drizzle delegates. - [Migrating from Prisma](https://better-drizzle.com/docs/guides/migrating-from-prisma.md): Move a Prisma project to Drizzle and better-drizzle step by step, keeping the same database and most of your query shapes. ## Read data - [Reads](https://better-drizzle.com/docs/querying/reads.md): findMany, findFirst, findOne, findUnique, count, and exists - and how to choose between them. - [Filters](https://better-drizzle.com/docs/querying/filters.md): The where model - scalar operators, logical combinators, null handling, and dropping to raw Drizzle SQL. - [null and undefined](https://better-drizzle.com/docs/querying/null-and-undefined.md): undefined means "no condition" and "leave unchanged"; null means SQL NULL. How each behaves in where, relation filters, JSON paths, and data. - [Selecting fields](https://better-drizzle.com/docs/querying/selecting-fields.md): where vs select vs include - which rows qualify, and which fields survive. - [Relations](https://better-drizzle.com/docs/querying/relations.md): Load related rows with include and select, count them with _count, and use many-to-many relations. - [Relation filters](https://better-drizzle.com/docs/querying/relation-filters.md): Filter rows by their related rows with is, isNot, some, every, and none. - [Pagination](https://better-drizzle.com/docs/querying/pagination.md): Use paginate() for offset pages and cursor() for cursor navigation. ## Write data - [Create, update & delete](https://better-drizzle.com/docs/writing/crud.md): Insert, change, and remove rows with create, createMany, update, updateMany, delete, and deleteMany. - [Upsert](https://better-drizzle.com/docs/writing/upsert.md): Create a row if it is missing or update it if it exists, for one row with upsert or many with upsertMany. - [Update many rows with different values](https://better-drizzle.com/docs/writing/update-each.md): updateEach updates many rows, each with its own values, in one UPDATE ... CASE statement. - [Atomic updates](https://better-drizzle.com/docs/writing/atomic-updates.md): Update counters and flags atomically in the database. - [Relation writes](https://better-drizzle.com/docs/writing/relation-writes.md): Attach, detach, and replace related rows from a single create, update, or upsert with connect, disconnect, and set. - [Throwing results](https://better-drizzle.com/docs/writing/throwing-results.md): Operations that return a nullable result plus a .throw() helper, so you can opt into exception-driven flow. ## Transactions & errors - [Transactions](https://better-drizzle.com/docs/advanced/transactions.md): Client-level transactions with nested savepoints, explicit rollback, lifecycle callbacks, retries, and options. - [Error handling](https://better-drizzle.com/docs/advanced/error-handling.md): Nullable results vs throwing, mapping errors at the boundary, and cross-dialect constraint detection helpers. - [Row locks](https://better-drizzle.com/docs/advanced/locks.md): Control concurrent row access with FOR UPDATE, FOR SHARE, skipLocked, noWait, table targeting, and transaction-only enforcement. - [Locking patterns](https://better-drizzle.com/docs/advanced/lock-patterns.md): Claim jobs, lock cursor pages, lock a joined relation, and handle lock timeouts. ## Advanced queries - [JSONB filters](https://better-drizzle.com/docs/querying/jsonb.md): Filter PostgreSQL JSONB columns with typed dot paths and the same operators as regular columns. - [Combining JSONB filters](https://better-drizzle.com/docs/querying/jsonb-combining.md): Use JSONB path filters with regular columns, logical operators, relation filters, every where helper, and expression indexes. - [JSONB updates](https://better-drizzle.com/docs/querying/jsonb-updates.md): Update nested keys of a PostgreSQL JSONB column with typed dot paths instead of rewriting the whole document. - [Array filters](https://better-drizzle.com/docs/querying/arrays.md): Typed filters for PostgreSQL array columns - membership, containment, length, and element predicates. - [Array updates](https://better-drizzle.com/docs/querying/array-updates.md): Append, prepend, remove, replace, and add unique values to PostgreSQL array columns in one atomic statement. - [Array indexing](https://better-drizzle.com/docs/querying/array-indexing.md): Index PostgreSQL array columns with GIN, check the plan, and see the measured cost of array filters and updates. - [Explain](https://better-drizzle.com/docs/querying/explain.md): Inspect the query plan of any read operation with .explain(). - [Prepared Statements](https://better-drizzle.com/docs/querying/prepared-statements.md): Compile a read once with param() and .prepare(), then execute it with new values. - [Raw SQL](https://better-drizzle.com/docs/advanced/raw-sql.md): Escape hatches for raw SQL - $raw for reads, $executeRaw for writes, and $rawUnsafe when you opt in. ## Customize - [Hooks](https://better-drizzle.com/docs/advanced/hooks.md): Client lifecycle hooks for auditing, tracing, metrics, and request-scoped logging. - [Client extensions](https://better-drizzle.com/docs/guides/client-extensions.md): Attach app-specific helpers and shared values to a Better Drizzle client with extends(). - [Dynamic repositories](https://better-drizzle.com/docs/guides/dynamic-repositories.md): Resolve a delegate by name at runtime with repository(), by TypeScript key or database table name. ## Plugins - [Plugins overview](https://better-drizzle.com/docs/plugins/overview.md): Package setup logic, query transforms, typed operation args, and reusable client/model extensions - without wrapping better() yourself. - [Timestamps](https://better-drizzle.com/docs/plugins/timestamps.md): Automatic createdAt / updatedAt management for better-drizzle, with app-managed and database-managed modes. - [UUIDs](https://better-drizzle.com/docs/plugins/uuid.md): Fill UUIDv7 or UUIDv4 primary keys on create, with optional ids in create types and 16-byte storage on MySQL and SQLite. - [Soft delete](https://better-drizzle.com/docs/plugins/soft-delete.md): Turn delete() into a recoverable state change, filter deleted rows by default, and add restore helpers. - [Cache](https://better-drizzle.com/docs/plugins/cache.md): Cache opted-in reads in Redis. Keys, serialization, and invalidation after writes are handled for you. - [Cache keys and invalidation](https://better-drizzle.com/docs/plugins/cache-keys.md): How the cache plugin builds keys, which versions an entry depends on, and what each write invalidates. - [Cache stores](https://better-drizzle.com/docs/plugins/cache-stores.md): The CacheStore interface, the Redis store, and an in-process store for tests. - [Tenant](https://better-drizzle.com/docs/plugins/tenant.md): Isolate tenants in every query, relation, write, and upsert, with fail-closed defaults and optional PostgreSQL RLS. - [Zod](https://better-drizzle.com/docs/plugins/zod.md): Generate per-table Zod schemas from your Drizzle schema and validate Better Drizzle operations at runtime. - [ata](https://better-drizzle.com/docs/plugins/ata.md): Describe your Drizzle models as JSON Schema and validate Better Drizzle operations against compiled validators. - [Rules](https://better-drizzle.com/docs/plugins/rules.md): Runtime guardrails for raw SQL, destructive writes, pagination, locks, and tenant context. - [Rule reference](https://better-drizzle.com/docs/plugins/rules-reference.md): Every rule the rules plugin enforces, when it fires, and its options. - [ESLint](https://better-drizzle.com/docs/plugins/eslint.md): Static Better Drizzle guardrails for IDE and CI feedback. - [Better Auth](https://better-drizzle.com/docs/plugins/auth.md): Use better-drizzle as the Better Auth database adapter, so auth reads and writes run through your plugins, hooks, and errors. - [Writing a plugin](https://better-drizzle.com/docs/plugins/writing-plugins.md): definePlugin - typed operation args, transforms, lifecycle hooks, client and model extensions, and plugin state. - [Plugin hooks](https://better-drizzle.com/docs/plugins/plugin-hooks.md): Lifecycle hooks, execution order, intercepts, and the context every plugin hook receives. - [Scopes and generated columns](https://better-drizzle.com/docs/plugins/plugin-scopes.md): Model scopes that filter every statement, generated columns that become optional in create inputs, and type-level resolvers. ## In production - [Typing results](https://better-drizzle.com/docs/guides/typing-results.md): How result types follow select and include, and how to name a result type. - [Typing services](https://better-drizzle.com/docs/guides/typing-services.md): Type reusable where, select, and include objects, services that take a client or a transaction, plugin clients, and meta. - [Service-layer patterns](https://better-drizzle.com/docs/guides/service-patterns.md): How to keep services thin and explicit on top of better-drizzle. - [Testing](https://better-drizzle.com/docs/guides/testing.md): Fast tests on in-memory SQLite with a fresh client per test. - [Test assertions](https://better-drizzle.com/docs/guides/testing-assertions.md): Assert on hooks, request metadata, plugins, and error codes against a real database. - [Testing on PostgreSQL](https://better-drizzle.com/docs/guides/testing-postgresql.md): Isolate tests on a shared database with rolled-back transactions and run PostgreSQL-only suites. - [Logging](https://better-drizzle.com/docs/guides/observability.md): Log query timings, slow queries, errors, and raw SQL with client hooks. - [Tracing](https://better-drizzle.com/docs/guides/observability-tracing.md): Correlate requests through meta, time transactions, and emit OpenTelemetry spans from hooks. - [Observability plugin](https://better-drizzle.com/docs/guides/observability-plugin.md): Package logging and timing hooks as one plugin that every service installs with one line. - [Multi-tenancy & request context](https://better-drizzle.com/docs/guides/multi-tenancy.md): Thread tenant and request metadata through hooks, plugins, and transactions. - [Framework integration](https://better-drizzle.com/docs/guides/frameworks.md): One client per process, a scoped client per request, and consistent HTTP error mapping in Next.js, Hono, Express, and Fastify. - [Recipes](https://better-drizzle.com/docs/guides/recipes.md): Short, copy-paste answers to everyday questions - conditional filters, counters, top N per group, upserts, search, and aggregates. - [Limitations & tradeoffs](https://better-drizzle.com/docs/guides/limitations.md): What better-drizzle does not do, where plugins stop applying, and where it stays native-first or explicit instead of adding silent abstractions. - [Troubleshooting & FAQ](https://better-drizzle.com/docs/guides/troubleshooting.md): Common better-drizzle errors grouped by symptom, with the error code or message, why it happens, and how to fix it. ## Reference - [Client](https://better-drizzle.com/docs/reference/client.md): better() - options, client-level methods, and the values exported from better-drizzle. - [Model delegate](https://better-drizzle.com/docs/reference/model-api.md): Every method on a table delegate - reads, writes, pagination, and the plugin-related helpers. - [Query options](https://better-drizzle.com/docs/reference/query-options.md): The full argument surface for reads, projections, ordering, pagination, filter operators, and metadata. - [Support matrix](https://better-drizzle.com/docs/reference/support-matrix.md): Dialect support for reads, relation loading, writes, upsertMany, locks, raw SQL, transactions, and package compatibility. - [Stability & semver](https://better-drizzle.com/docs/reference/stability.md): What better-drizzle considers stable in the 0.3.x line, how the unified package is versioned, and what counts as a breaking change. - [Error helpers](https://better-drizzle.com/docs/reference/errors.md): BetterDrizzleError, its error codes, and cross-dialect constraint detection helpers. ## Performance - [Benchmarks](https://better-drizzle.com/docs/performance/benchmarks.md): Wrapper overhead vs raw Drizzle across latency and memory, measured with fair API-parity comparisons. - [Benchmark parity](https://better-drizzle.com/docs/performance/parity.md): How the benchmark suite keeps overhead numbers honest - equivalent work on both sides, verified before anything is timed. ## Resources - [AI Agents](https://better-drizzle.com/docs/ai.md): Use better-drizzle with Claude Code, Codex, Cursor, Copilot, ChatGPT, and other AI agents. - [Upgrading](https://better-drizzle.com/docs/guides/upgrading.md): Pick the upgrade guide for the version you are on. - [Upgrade to 0.3 (Drizzle ORM 1.x)](https://better-drizzle.com/docs/guides/upgrading-0-3.md): Move from better-drizzle 0.2 on Drizzle 0.x to 0.3 on Drizzle ORM 1.x with defineRelations. - [Changes in 0.3](https://better-drizzle.com/docs/guides/upgrading-0-3-changes.md): Runtime behavior changes and new features in better-drizzle 0.3 that the typecheck does not catch. - [Upgrade to 0.2 (unified package)](https://better-drizzle.com/docs/guides/upgrading-0-2.md): Replace the scoped @better-drizzle/* plugin packages with subpath imports of the single better-drizzle package. ## Optional - [GitHub repository](https://github.com/almeidazs/better-drizzle): source code and issues. - [npm package](https://www.npmjs.com/package/better-drizzle): published versions.