Stability & semver
What better-drizzle considers stable in the 0.2.x line, how the unified package is versioned, and what counts as a breaking change.
0.2.x is the current 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 trueEach 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.2.x
- the package entrypoints listed in
exports(.,/plugins,/eslint,/rules,/soft-delete,/timestamps,/zod) - 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, andoperationArgs - the published support matrix for PostgreSQL, SQLite, and MySQL
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:
- explicit support
- explicit unsupported behavior with a structured error
It does not prefer hidden userland fallbacks that materially change
performance or semantics without saying so. upsertMany on MySQL 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