New to Jamsocket: Y-Sweet, our batteries-included service for realtime apps.Learn More

What’s new in Y-Sweet 0.7.0: offline support and more!

2024-12-18

Paul Butler

We recently released Y-Sweet 0.7.0. Here’s a look at what’s new:

Ground-up YSweetProvider rewrite

At its core, Yjs is an in-memory CRDT data structure. The data structure itself is not aware of the network or storage. Applications can synchronize a Yjs document over a specific transport (like WebSocket or WebRTC) using a provider for that transport.

Until 0.7.0, Y-Sweet used a forked version of the y-websocket provider maintained by the Yjs community. While this is a good provider, it was not amenable to some of the functionality we wanted to build on top of it. For Y-Sweet 0.7.0, we rewrote the provider from scratch, bringing with it better offline support, reconnection logic, and connection/sync status observability.

Offline support

YSweetProvider now includes IndexedDB support, making offline support as easy as passing offlineSupport: true when constructing the provider (<YSweetProvider offlineSupport={true} /> if you use our React bindings).

All major browsers store IndexedDB as plain text on disk. To avoid exposing your users’ data, we encrypt the data on the client before we store it in the database, which allows us to piggyback on app-bound encryption in Chrome and Edge. You can read more about this approach in this Browsertech post.

Improved reconnect handling

As part of the rewrite, we made some improvements to the reconnect loop to make it faster and more robust. For example, if the client is in a reconnect loop and the browser fires an online event, we skip the normal cooling-off period and immediately try to reconnect.

Connection & sync status listeners

Browsers are often slow to detect WebSocket connection closure when the connection is lost — we have observed up to 90 seconds for Chrome on a VPN! As part of the reconnect handling improvements, we extended the protocol with a passive/active heartbeat. When the connection is actively in use, existing inbound traffic plays the role of the heartbeat. During lulls in the traffic, an active heartbeat kicks in.

This status is exposed through a new connection-status event type, and as useConnectionStatus() if you use our React hooks.

We also now provide a local-changes event, which passes a value of true when a local change is made and false when all local changes have been received by the server. This is exposed in the React hooks as useHasLocalChanges().

Deprecating Wasm/Cloudflare support

Y-Sweet has historically supported two deployment targets: a native Linux app, and a WebAssembly module that runs as a Cloudflare Durable Object. This is possible because most of the underlying implementation belongs in y-sweet-core, which is designed to support native and WebAssembly targets.

As of 0.7.0, we are deprecating WebAssembly support in y-sweet-core. Future releases with the 0.7.x minor version will continue to support WebAssembly and Cloudflare deployment. Starting with 0.8.0, WebAssembly will no longer be a supported target for y-sweet-core, and we will not support Cloudflare deployment.

This was a tough decision. We never like to take away functionality from an open source project. But it has become clear that the need to support WebAssembly as well as native was creating a big burden to contributions both from our own team and the open source community.

Additionally, it became clear that our roadmap was much more tractable if we drop the WebAssembly support. In particular, we have redesigned the storage engine to take advantage of multithreaded execution, which is not available on Cloudflare’s Workers platform.

A core principle of Y-Sweet development continues to be that you should be able to self-host it. To that end, we are building support for Plane directly into Y-Sweet to allow you to run Y-Sweet at scale as a distributed system. (Single-node deployments, which do not require Plane, will continue to work as they do today.)

Managed storage & free tier

We recently announced managed storage for Y-Sweet on Jamsocket. This means that you can create a Y-Sweet project with persistence without attaching your own S3 bucket. You can still attach an S3 bucket if you want to, of course, but that’s no longer a prerequisite.

Along with managed storage, we’ve also introduced a free tier providing 10GB of storage per account.

New resources for getting started

  • create-y-sweet-app makes it easier to bootstrap a Next.js or Remix app preconfigured with Y-Sweet.
  • y-sweet-supabase-demo is an example app showing how Y-Sweet can be used along with Supabase to implement auth, sharing links, and document listings.
  • Our new BlockNote tutorial shows how to use the Notion-like BlockNote component in a Y-Sweet application.

Welcoming Jake to the team

Jake Lazaroff recently joined the Jamsocket engineering team. You may have seen Jake’s writing on CRDTs around the web (A Local-First Case Study, Making CRDTs 98% More Efficient, Building a Collaborative Pixel Art Editor with CRDTs, An Interactive Intro to CRDTs). Jake's depth of understanding of CRDTs and attention to craft make him a great addition to the team, and I’m excited about how we’ll be able to make Y-Sweet better with Jake on board.

On the horizon

As we round out 2024, we have an ambitious roadmap for Y-Sweet in 2025. Work is already underway on a new storage engine with history support, read-only access tokens, and more.

If you’d like to suggest features, come say hi on Discord or open an issue on GitHub.

Ready to build?

Getting started is simple and quick. Explore documentation, or sign up and start building today.

Jamsocket