I Shipped...

20 April 2026 (2PRs)

passphrase and passkey backup/restore UI for starters

I added an AuthBackup component to four local-first starter templates with recovery phrase and passkey backup/restore support. This gives users a way to recover their account if they lose their device.

the create-jazz CLI scaffolder

I built an interactive CLI scaffolder so you can run npm create jazz to bootstrap a new project. It prompts for your framework choice and auth mode, then fetches the right starter template, resolves dependencies, and initialises git.

18 April 2026 (2PRs)

an alphaTab dependency update and Vite integration

I updated the alphaTab music notation library to its latest version and added a Vite-based sample project. alphaTab is a library for rendering and playing guitar tablature and sheet music in the browser.

experimental clock sync for clients with drifting system clocks

I added an optional feature that fixes a tricky timing problem. When a user’s device clock is slightly wrong (drifting), it can cause data to be timestamped incorrectly. This feature uses the existing ping messages between the client and server to estimate how far off the clock is, and quietly corrects timestamps so they’re accurate.

17 April 2026 (3PRs)

a fix for worker URL resolution in bundlers

I switched from dynamic runtime URL resolution to a static new URL(...) pattern for the web worker bootstrap. This lets bundlers like Vite, webpack, and Next.js/Turbopack detect and co-bundle the worker and WASM files correctly.

a module type declaration fix for the jazz-wasm package

I added "type": "module" to the jazz-wasm package.json. Without it, running the CLI via npx or bunx would fail with an ERR_REQUIRE_CYCLE_MODULE error because Node.js was treating the ES module output as CommonJS.

pruned tests in the moon-lander example

I deleted 6 test files (about 2,450 lines) from the moon-lander-react example that weren’t actually exercising Jazz’s sync capabilities. I kept the 4 genuine cross-client sync tests that test what the example is really about.

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.