@byline/db-mysql ships in 4.8.0 as preliminary, not as fully supported MySQL support. This issue tracks what has to be true before that qualifier comes off, so the status has a visible close condition rather than being an open-ended caveat.
Where it already stands
Both halves of the MySQL implementation are now complete.
The storage layer passes the entire shared @byline/db-conformance behavioural suite — the same suite @byline/db-postgres runs — with identical results across document storage, versioning, patches, workflow, populate, and admin auth.
Search is no longer a gap. @byline/search-mysql shipped in 4.9.0 and passes the full @byline/search-conformance aggregate suite against a live database, the same suite @byline/search-postgres passes, with its own independent numbered migration stream.
What remains is tooling, not implementation. A MySQL installation works; it just has to be wired by hand.
Criteria
On the CLI criterion
Worth recording what this involves, since it is more than a prompt. packages/cli has no MySQL awareness at all today — src/lib/pg-url.ts, src/phases/db.ts, src/phases/db-init.ts, src/manifest/deps.ts, and src/manifest/env.ts are all Postgres-shaped, and src/phases/db-init.ts applies storage migrations by running drizzle's node-postgres migrator over src/templates/migrations/.
That last point is the structural one: neither @byline/db-postgres nor @byline/db-mysql publishes its storage migrations. Both set files: ["dist"], neither exports a migrate() entry point, and the .sql files live under src/database/migrations/ where tsc does not copy them. The CLI carries its own bundled copy of the Postgres migrations instead. So "CLI adapter selection" implies deciding how MySQL's three storage migrations reach an installed project — bundling a second copy in the CLI, or giving the adapters a published migration surface the way both search packages already do (files: ["dist", "migrations"] plus an embedded-SQL migrate(pool) that stays bundler-safe).
Not blocking, but worth resolving alongside
Closing this
When the CLI criterion is met: drop the status banner from the adapter README, update the note in Core Document Storage, and say so in a release changeset.
Design and plan: specs/2026-07-24-db-mysql-adapter-design.md
@byline/db-mysqlships in 4.8.0 as preliminary, not as fully supported MySQL support. This issue tracks what has to be true before that qualifier comes off, so the status has a visible close condition rather than being an open-ended caveat.Where it already stands
Both halves of the MySQL implementation are now complete.
The storage layer passes the entire shared
@byline/db-conformancebehavioural suite — the same suite@byline/db-postgresruns — with identical results across document storage, versioning, patches, workflow, populate, and admin auth.Search is no longer a gap.
@byline/search-mysqlshipped in 4.9.0 and passes the full@byline/search-conformanceaggregate suite against a live database, the same suite@byline/search-postgrespasses, with its own independent numbered migration stream.What remains is tooling, not implementation. A MySQL installation works; it just has to be wired by hand.
Criteria
validateSearchConfigno longer forces MySQL installations onto a no-op provider; registermysqlSearch({ pool, defaultLocale })and applymigrate(pool)from@byline/search-mysql. See Search on MySQL in the adapter README.mysql:8.0: that is the documented engine floor, and pinning it is what actually exercises the floor rather than a version comfortably above it. A version matrix on every run was descoped to keep CI times short — 9.x is covered by local development (mysql/docker-compose.ymlrunsmysql:latest) and can be run manually when a MySQL release lands. The timezone gap was closed, because it was the one that could hide a real regression: a non-UTC leg re-runs both adapter conformance suites underTZ=Asia/Kathmandu(UTC+5:45, so it also catches whole-hour-offset assumptions).byline initscaffolds a Postgres installation only. Adding MySQL means hand-editingbyline/server.config.ts: swapping the adapter and admin-store imports, swappingpostgresSearchformysqlSearch, and pointing the env at a MySQL connection string. The installer should offer the choice and emit correct wiring for either. This is now the only blocker.On the CLI criterion
Worth recording what this involves, since it is more than a prompt.
packages/clihas no MySQL awareness at all today —src/lib/pg-url.ts,src/phases/db.ts,src/phases/db-init.ts,src/manifest/deps.ts, andsrc/manifest/env.tsare all Postgres-shaped, andsrc/phases/db-init.tsapplies storage migrations by running drizzle'snode-postgresmigrator oversrc/templates/migrations/.That last point is the structural one: neither
@byline/db-postgresnor@byline/db-mysqlpublishes its storage migrations. Both setfiles: ["dist"], neither exports amigrate()entry point, and the.sqlfiles live undersrc/database/migrations/wheretscdoes not copy them. The CLI carries its own bundled copy of the Postgres migrations instead. So "CLI adapter selection" implies deciding how MySQL's three storage migrations reach an installed project — bundling a second copy in the CLI, or giving the adapters a published migration surface the way both search packages already do (files: ["dist", "migrations"]plus an embedded-SQLmigrate(pool)that stays bundler-safe).Not blocking, but worth resolving alongside
ROW_NUMBER()window inside a derived table, used by both current-version views) as a question to answer before GA. Postgres has a benchmark sweep; MySQL has no counterpart.Closing this
When the CLI criterion is met: drop the status banner from the adapter README, update the note in Core Document Storage, and say so in a release changeset.
Design and plan:
specs/2026-07-24-db-mysql-adapter-design.md