I Shipped...

24 August 2026 (1PR)

a fix that blocks client access to generated Better Auth tables

I added deny rules for every generated Better Auth table, including names that do not work as JavaScript identifiers. This keeps ordinary clients from reading or changing authentication records while the backend adapter can still use them.

21 August 2026 (1PR)

aligned docs with current APIs

I brought the guides, examples, and search index back into line with the current public APIs. I also added a reference guide for the new core and explained transactions, durability, and errors around the unified mutation results.

20 August 2026 (9PRs)

unified database mutation results

I replaced several different write-result shapes with one consistent database mutation result. Inserts and restores still return their rows, while updates, upserts, and deletes clearly return no row, and each result keeps its value, batch ID, and wait operation.

stabilised browser worker timing

I stabilised browser tests that use a file worker by limiting how many browser files run at once and allowing slow operations more time before failing. This stops the browser's main work from being starved by too much parallel file activity, while still warning when responsiveness falls below the target.

separated Vue provider ownership

I separated the Vue provider that creates and shuts down a database client from the provider used with a client supplied by the caller. This makes it clear who owns the client's lifetime, keeps rapid configuration changes in order, and updates the examples and documentation.

separated Svelte provider ownership

I separated the Svelte provider that creates and shuts down a database client from the provider used with a client supplied by the caller. This makes it clear who owns the client's lifetime and updates the examples and documentation to use the right provider.

separated Solid provider ownership

I separated the Solid provider that creates and shuts down a database client from the provider used with a client supplied by the caller. This makes it clear who owns the client's lifetime and lets later configuration recover after a shutdown failure.

saved Vite app IDs before startup

I fixed a development-startup race where a generated app ID was not saved before Vite's server and file watcher began. The app ID is now saved during configuration, and the same preparation is used by direct runtime and SvelteKit startup.

refreshed shared query results after authorisation changes

I fixed a stale-data bug in shared server query results. When a user's permissions changed, a new subscription could claim it already had the current rows and keep seeing old or unauthorised data. The server now sends the full current result when the permission state is out of date, while unchanged reconnects keep the smaller update.

made starter recovery wait for saved data

I fixed a race in the hybrid starter tests where account recovery could begin before the optimistic write it was meant to restore had been saved. The tests now wait for the saved status first, so they check the real recovery sequence instead of competing with it.

added support for WorkOS JWT subjects

I added support for WorkOS identity IDs in server authentication, while keeping the existing UUID-based IDs working. The TypeScript and Rust sides now apply the same rules, so permissions and identity checks agree across the system.

19 August 2026 (9PRs)

quieted misleading React test warnings

React Todo tests were doing asynchronous work outside the wrapper React expects, so they printed warnings even when the tests passed. I put the waits inside the right wrapper and ran the browser files one at a time because they share temporary server state, leaving the tests green without the noisy output.

brought Moon Lander's write tests up to date

Moon Lander had moved to a newer way of saving data, but its test helper still pretended the old methods existed. I updated that helper to follow the current insert-and-update flow, so the four tests can reach their real assertions again.

Better Auth support for non-UUID users

I made Better Auth work when user IDs are ordinary strings instead of UUIDs. Browser and server code now turn the same ID into the same internal identity, including for WebSocket connections, while keeping the original ID available and protecting built-in session fields.

transaction overlays scoped per table and row

I fixed pending transaction overlays that were keyed only by row ID. They now also include the table name, so two tables can safely have the same row ID without one table's pending value hiding the other's.

transaction IDs in the public Rust API

I renamed the public Rust API's batch terminology to transaction terminology. Internal query-engine and wire-format names stay unchanged where they are implementation details, while the public API, bindings, examples, and tests now use the clearer vocabulary.

safer authentication and insert configuration types

I tightened the configuration types for inserts and authentication so incompatible options cannot be combined accidentally. I also made local-first authentication return its new token through configuration inspection without exposing the original secret.

removal of deprecated authentication and permissions options

I removed two old configuration options that had newer replacements: the authentication secret storage key and the combined permissions setting. The affected example now uses the current, separate options.

regression coverage for rejected ancestry and global reads

I added focused tests for two synchronisation guarantees in the new core. They prove that a rejected update does not block a later fresh commit, and that global reads eventually use the authoritative remote value while a local write remains pending.

recovery from transient storage commit failures

I made the database recover cleanly when a storage commit fails before anything is durably written. The in-memory state and sequence clock are restored, so an exact retry can succeed instead of leaving the database permanently poisoned.