I Shipped...

15 April 2026 (1PR)

a SvelteKit Vite plugin for Jazz

I built a new Vite plugin for SvelteKit projects that manages the Jazz dev-server lifecycle automatically. It supports embedded server mode, connecting to an external URL, or reading the config from environment variables.

14 April 2026 (1PR)

a dedicated docs section for read durability tiers

I promoted read durability from a footnote to its own top-level section on the reading/queries page, with tier definitions, per-tier guidance, and reference material so developers can choose the right durability level for their use case.

10 April 2026 (3PRs)

a fix for a Better Auth race condition

When signing in with Better Auth, a slow /get-session request could arrive after the user had already successfully signed in via a different flow. Because the slow response said “no session”, it would log the user straight back out again. I added a little counter that increments each time the user authenticates, and we attach it as a header to session requests — if a stale response comes back with an old counter value, we now know to ignore it.

a fix for a hang in createJazzContext when schema migrations fail

If your app’s migration tried to load a piece of data whose shape didn’t match any of the allowed schema variants, Jazz would silently get stuck forever instead of telling you what had gone wrong. The error was being thrown inside an internal loop that swallowed it, so the underlying promise never settled. I added a dedicated error type for this case and caught it in the right place, so loads now fail cleanly as “unavailable” rather than hanging your app.

changeset entries documenting two bug fixes

I added changeset entries to document two bug fixes — one for a hang when loading data with mismatched schemas during migrations, and one for a race condition in Better Auth that was logging users out. Changesets are how Jazz tracks what changed between versions, so these make sure the fixes get properly noted in the changelog.

8 April 2026 (5PRs)

a friendlier API for permission relation names

I updated allowedTo so you can write allowedTo.read("project") instead of having to specify the full “projectId” suffix. It tries an exact match first, then falls back to adding “Id” or “_id” for backwards compatibility.

a moon lander multiplayer game example

I built a multiplayer moon lander game as an example app for Jazz using React and Phaser. It demonstrates real-time multiplayer sync — multiple players can fly their landers at the same time and see each other’s movements.

From implementations and a row_input! macro

I added From<T> implementations on the Value type for common Rust types and introduced a row_input! macro for building HashMaps more ergonomically. This deleted about 250 lines of boilerplate across the codebase.

migration of example code to row_input! macro

I migrated the three remaining hand-rolled HashMap call sites in the examples to use the new row_input! macro, and enabled SQLite for persistent storage in the todo-server tests.

Rust examples for the files-and-blobs docs page

I added Rust code tabs (create, load, delete) to the files-and-blobs documentation page, matching the TypeScript/Rust tab pattern used across the rest of the docs.

7 April 2026 (1PR)

an advanced internals reference page for the docs

I wrote a new Advanced Internals page covering the Jazz data model, browser architecture, query engine, sync protocol, schema evolution, and durability signals. I also fixed several documentation gaps along the way.

3 April 2026 (2PRs)

a fix for Svelte state_referenced_locally warnings

I moved prop reads in JazzSvelteProvider and SyntheticUserSwitcher into reactive contexts so the Svelte 5 compiler no longer emits state_referenced_locally warnings. I also improved lifecycle handling in both components.

example app alignment with docs and permission fixes

I standardised snake_case field naming across all todo and file-upload examples to match the docs convention, added missing permissions.ts files, fixed a bug in wequencer’s instrument seeding, and cleaned up undocumented config.

1 April 2026 (4PRs)

a unified signature for createInviteLink across core and browser

Our createInviteLink function had two different shapes depending on whether you imported it from the core library or from the browser/React Native wrappers. That was confusing for users and, in particular, was causing AI coding assistants to generate broken code because they’d mix up the two forms. I added an options-object overload to the core version so it matches the browser version, and cleaned up some duplicate implementations along the way. The old positional form still works, but it’s now deprecated.

a Vue 3 example app showcasing Jazz

I built a complete Vue 3 example app demonstrating Jazz as a local-first relational database. It covers schema definitions, permissions, and file handling — everything you need to see how Jazz works with Vue.

file and blob storage for the Wequencer example

I migrated the Wequencer example app from storing sound data as inline bytes to using Jazz’s proper file/blob storage pattern with createFileFromBlob. This is the recommended way to handle binary data in Jazz.

updated dev docs reflecting the build-less workflow

I updated the developer documentation to reflect the current build-less status quo, adding sections on the project layout (schema.ts, permissions.ts, migrations), the defineApp pattern, and type helpers.

31 March 2026 (3PRs)

a change to install wasm-pack via cargo in jazz2

I removed the npm wasm-pack package and switched to installing it via cargo instead. This eliminates the axios transitive dependency, reducing the risk of supply chain vulnerabilities.

a change to install wasm-pack via cargo instead of npm

We had been pulling in wasm-pack as an npm package, which dragged in axios and another helper library as transitive dependencies — more things to trust from the npm ecosystem. Since anyone building our Rust/WASM crate already has a full Rust toolchain installed anyway, I switched us to installing wasm-pack directly via cargo install. One less set of supply-chain risks to worry about.

a fix for InvalidSignature errors when concurrent writes happen

When two writers were updating the same piece of data at the same time, Jazz would sometimes throw an InvalidSignature error on load. The cause was a classic off-by-one: our code was using a count where it needed an index, so it was fetching one more transaction than the stored signature actually covered. I changed that one number and the storage layer now copes with concurrent writes properly.