better-drizzle
Reference

Stability & semver

What better-drizzle considers stable in the 0.3.x line, how the unified package is versioned, and what counts as a breaking change.

0.3.x is the Drizzle ORM 1.x release line of better-drizzle.

0.2.0 changed how plugins are distributed

The official plugins are no longer published as separate @better-drizzle/* packages. Everything ships inside the single better-drizzle package as subpath exports. See the upgrade guide for the one-step migration.

One package, one version

There is a single published manifest. better-drizzle and every official plugin move together, so there is no version matrix to reconcile:

import { version } from 'better-drizzle';
import { version as zodVersion } from 'better-drizzle/zod';

version === zodVersion; // always true

Each entrypoint still re-exports version so a plugin can report itself in logs, but the value is always the package version.

What is considered stable in 0.3.x

  • the package entrypoints listed in exports (., /plugins, /eslint, /rules, /soft-delete, /timestamps, /zod); /ata and /cache are experimental (below)
  • documented delegate methods and their result shapes
  • documented client methods
  • documented option names on better(), on each operation, and on official plugins
  • the plugin authoring API: definePlugin, hooks, transforms, extensions, and operationArgs
  • plugin operation intercepts: intercept(ctx) with next(), annotate(), skipAfterHooks(), and params, plus the annotations after hooks receive (see intercepts)
  • the published support matrix for PostgreSQL, SQLite, and MySQL

Experimental in 0.3.x

  • better-drizzle/cache and better-drizzle/cache/redis: option names, per-call cache arguments, $cache methods, the store interface, and the stored entry format can change in a patch release while the plugin matures. Pin an exact version if you depend on it, and expect cached entries to be discarded after an upgrade. The plugin is built on intercept, which is part of the stable plugin API above; only the cache plugin itself is experimental.
  • better-drizzle/ata: JSON Schema validation built on ata-validator, intended as a faster alternative to better-drizzle/zod. Option names, the $ata API, and the generated schemas can change in a patch release. Pin an exact version if you depend on it.
  • better-drizzle/tenant (from 0.4.0, experimental through 0.4.x): option names, the $tenant / $withoutTenant API, and error details can change in a patch release. Pin an exact version if you depend on it. See tenant.

Experimental entrypoints are not covered by the semver policy below until they move to the stable list.

Anything reachable only through a deep import path (better-drizzle/dist/...) is internal and can change in a patch.

Semver policy

better-drizzle follows semver intent, with extra conservatism around types:

  • patch - bug fixes, doc fixes, test additions, internal optimizations, support-matrix clarifications
  • minor - additive APIs, new plugin hooks, new documented options, new entrypoints
  • major - behavior changes, removed exports, renamed options, changed result shapes, or stricter semantics that can break existing code

While the package is pre-1.0, a breaking change lands in a minor bump (0.2.x → 0.3.0) and is always called out in the release notes with a migration path.

Type-level compatibility

TypeScript users depend on inference as part of the product. Because of that:

  • changes that break valid user code through types are treated as breaking changes
  • documented generic types and exported helper types are part of the public surface
  • public API snapshots are generated in the repository to make surface drift easier to review

Dialect policy

When a dialect cannot support a feature safely or honestly, the project prefers:

  1. explicit support
  2. explicit unsupported behavior with a structured error

It does not prefer hidden userland fallbacks that materially change performance or semantics without saying so. An upsertMany target MySQL cannot honor and row locks on SQLite fail fast for exactly this reason.

Release notes

Every published version should have:

  • a changelog entry
  • updated docs when user-facing behavior changes
  • a documented migration path for anything breaking
  • passing smoke-consume checks against the built tarball

On this page