Skip to content
Open
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
0f8100f
blog: add Yjs durable streams on Electric Cloud draft
balegas Mar 25, 2026
2ffd824
draft
balegas Mar 26, 2026
d143c47
docs: embed Territory Wars demo in Yjs blog post
balegas Mar 28, 2026
3bf15c6
fix: use explicit index.html in territory wars iframe src
balegas Mar 28, 2026
b09a1ce
docs: update territory wars bundle — remove board size selector
balegas Mar 28, 2026
32b18af
docs: re-add Territory Wars demo embed to blog post
balegas Mar 28, 2026
83b09bf
docs: shorter demo section, fixed 600px iframe height, rebuilt bundle
balegas Mar 28, 2026
1f5afa6
fix: remove border from territory wars iframe
balegas Mar 28, 2026
cc1cae2
docs: rename "try the demo app" to "check the example app"
balegas Mar 28, 2026
fee16a0
docs: move demo section before get started
balegas Mar 28, 2026
397d463
docs: halved board height, 450px iframe, rebuilt bundle
balegas Mar 28, 2026
153a28e
docs: 3-room pagination, 500px iframe height, rebuilt bundle
balegas Mar 28, 2026
de80976
docs: update bundle — 30x25 board to fill iframe height
balegas Mar 28, 2026
c84835f
blog: add header image for yjs durable streams post
balegas Mar 28, 2026
db7ee45
blog: fix dead link in outline file
balegas Mar 28, 2026
cebc5b9
blog: simplify how it works section to high-level overview
balegas Mar 28, 2026
ca5ff5d
docs: update territory wars bundle — 30x25 board, rate-limited touch
balegas Mar 29, 2026
dbb210b
docs: update territory wars bundle — random names, rate-limited touch
balegas Mar 30, 2026
6650613
docs: update territory wars bundle — lobby subtitle
balegas Mar 30, 2026
9269f37
docs: demo section — focus on Electric Cloud, not game mechanics
balegas Mar 30, 2026
8dec0a3
docs: rematch button, mobile-friendly demo text, rebuilt bundle
balegas Mar 30, 2026
75ff484
docs: update description, excerpt, demo text, our→an
balegas Mar 30, 2026
05e9fa9
docs: shorter, punchier excerpt
balegas Mar 30, 2026
7f3fd68
docs: excerpt — fan-out via CDN, agentic systems
balegas Mar 30, 2026
2dde8a8
docs: add territory wars demo listing, update blog post
balegas Mar 31, 2026
9c3049f
docs: fix prettier formatting in SnapshotSyncDiagram
balegas Mar 31, 2026
eab02b9
fix(sync-service): Improve shutdown times (#4066)
magnetised Mar 30, 2026
952b75f
fix: preserve char(n) space padding in snapshot/subset queries (#4044)
alco Mar 30, 2026
d524a14
fix: Resolve pending shapes in FlushTracker when consumer process rec…
alco Mar 30, 2026
d042259
feat(typescript-client): add move-in event support (#4043)
kevin-dp Mar 30, 2026
a000e20
fix(elixir-client): Add required headers to mock responses (#4072)
magnetised Mar 30, 2026
d3fd29a
chore: publish new package versions (#4048)
github-actions[bot] Mar 31, 2026
048f1e7
docs: update demo text, add StreamDB reference, remove scores sentence
balegas Mar 31, 2026
10d0fc3
chore: update territory wars demo bundle
balegas Apr 1, 2026
498b548
chore: update territory wars demo bundle
balegas Apr 1, 2026
b523b79
chore: update territory wars demo bundle
balegas Apr 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions website/blog/posts/2026-03-25-yjs-durable-streams-on-electric-cloud.md
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tweak the filename date to 31st March. N.b.: fixing any links referring to it.

Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
title: 'Yjs CRDTs over HTTP on Durable Streams'
description: >-
y-durable-streams is a new open-protocol Yjs provider with built-in compaction, presence, and CDN caching built on Durable Streams.
excerpt: >-
Sync Yjs documents over plain HTTP. y-durable-streams brings built-in compaction, real-time presence, and fan-out via CDN to collaborative apps and agentic systems.
authors: [balegas]
image: /img/blog/yjs-durable-streams-on-electric-cloud/header.png
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The image is just slightly not vertically centered. It needs the top padding cropped out slightly. Ideally exported as an 1536 x 947 pixel image.

tags: [durable-streams, cloud, release, sync, collaboration]
outline: [2, 3]
post: true
published: true
---

[Yjs](https://yjs.dev) is the de facto library for collaborative editing on the web. It's battle-proven, CRDT-based, and powers tools like [TipTap](https://tiptap.dev), [CodeMirror](https://codemirror.net), [BlockNote](https://www.blocknotejs.org/) and more. And it's not just collaboration between humans anymore — agents are increasingly editing documents, generating code, and filling in forms alongside users. Whether it's humans or agents collaborating, they need reliable, conflict-free sync.
Copy link
Copy Markdown
Contributor

@thruflo thruflo Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would perhaps say what we're releasing here.

I.e.: "Yjs is X, it's increasingly for agents and <today we're releasing ...>."

What is it that the reader would be trying now when they "Try it now" below?! It's not Yjs, it's our new Durable Streams Yjs integration ...


>[!info] 🚀&nbsp; Try it now
>Sign up to [Electric&nbsp;Cloud](https://dashboard.electric-sql.com), create a&nbsp;Yjs service, and connect your app.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(The create link must use the intent link).

>See the [`y-durable-streams` source](https://github.com/durable-streams/durable-streams/tree/main/packages/y-durable-streams) and [demo&nbsp;app](https://github.com/durable-streams/durable-streams/tree/main/examples/yjs-demo) on&nbsp;GitHub.

## The problem with WebSockets
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The title seems a bit odd to me. This is an article about our Yjs integration. Where did WebSockets come from? Could this first para be mixed in below, so the body of the article leads with what we've built?


Most Yjs setups are built on WebSockets to relay updates to clients. WebSockets are point-to-point connections with no fan-out distribution. They require sticky connections and content can't be cached at a CDN, which means there is a latency penalty for every user or agent that needs to retrieve the initial state of a document.

There is no standardized reference implementation if you want to implement this yourself. There are hosted services you can buy, but that means vendor lock-in and a new piece of infrastructure to add to your&nbsp;stack.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very LLM-tell.


## Yjs on bare HTTP
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this say "Yjs on Durable Streams"?


We've built [`y-durable-streams`](https://github.com/durable-streams/durable-streams/tree/main/packages/y-durable-streams) — a new Yjs provider on [Durable&nbsp;Streams](/primitives/durable-streams), an open HTTP protocol for persistent, resumable, real-time streams.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the sentence/para that I'd love to be in the intro above.


Instead of WebSocket relay servers, document updates flow through plain HTTP. Clients POST edits and subscribe for real-time updates via SSE or long-polling — no persistent connections, no sticky sessions. Because it's standard HTTP, it works with the infrastructure you already have: load balancers, reverse proxies, CDNs. Snapshots are cacheable at the edge, so fan-out scales without extra&nbsp;effort.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This focuses on HTTP and connection details. Is the lede not the para below? What do Durable Streams do -- they provide persistence, durability and sync. Plus with this impl also compaction etc.

I would prioritize what this does rather than tilting at the WebSocket straw man.


The provider handles document sync, server-side compaction, and awareness out of the box. It's open source, backed by an [open protocol specification](https://github.com/durable-streams/durable-streams/blob/main/packages/y-durable-streams/YJS-PROTOCOL.md), and now live on [Electric&nbsp;Cloud](/cloud).

## How it works

Each document is backed by a durable stream — a persistent, append-only log. Every edit is appended to the stream, and all connected clients receive it in real time. When a new client joins, it doesn't replay the full history. Instead, it loads a **snapshot** — a compacted version of the document at a point in time — and subscribes for live updates from there. As documents grow, the server automatically compacts accumulated updates into new snapshots, so initial sync stays&nbsp;fast.

Presence — cursors, selections, user info — is handled through **awareness streams**. These are ephemeral: clients only receive the latest changes, and each stream has a built-in TTL that garbage-collects stale state from disconnected clients. A default awareness stream is created with every document, and you can create additional named ones for different&nbsp;purposes.

For the full details, see the [Yjs Durable Streams Protocol](https://github.com/durable-streams/durable-streams/blob/main/packages/y-durable-streams/YJS-PROTOCOL.md)&nbsp;specification.

## Demo
Copy link
Copy Markdown
Contributor

@thruflo thruflo Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The demo is totally awesome. It just needs a little more packaging. This is the main feedback I wanted to relay on the post -- we can get loads more value from the work with some simple tweaks.

Right now the demo is an interactive iframe embed in the page. However, it's not obvious that it's interactive or that it's multi-player or that it's an app at all.

I suggest:

  1. screen recording a 30 - 45 second screencast of using the game. Use Screen Studio so you record yourself as well and just talk about the game and how it's built whilst using it.
  2. publish this to the ElectricSQL YouTube and use the YoutubeEmbed component to embed the video below the warning box in the header above -- that way it's impossible to miss it and it's obvious it's a screencast video of a demo app
  3. here in the page if we want to embed the app then it needs clearer signposting that it is indeed an embedded interactive app, not just an embedded screenshot. I would also personally have a primary button that opens the app in target blank (or a popover window) because I think that will be easier for people to test the multiplayer and use as an app vs the embed here
  4. if possible, publish a /demos/territory-wars demo, using the markdown front matter of the demo page to link to the video, demo app and source then you can embed / link to that from the page here.


A demo of `y-durable-streams` live on Electric&nbsp;Cloud. Game state is stored in a Yjs Y.Map — each grid cell is a CRDT entry with last-writer-wins conflict resolution. Player presence uses awareness streams. Open it in multiple tabs, share the room link, or try it on your&nbsp;phone.

<iframe src="/demos/territory-wars/index.html" style="width:100%;height:500px;border:none" sandbox="allow-same-origin allow-scripts allow-popups" allow="clipboard-write"></iframe>

## Get started

Here's how to set up a collaborative text editor. Create a Yjs document with awareness and point it at your&nbsp;endpoint:

```typescript
import { YjsProvider } from '@durable-streams/y-durable-streams'
import { Awareness } from 'y-protocols/awareness'
import * as Y from 'yjs'

const doc = new Y.Doc()
const awareness = new Awareness(doc)

const provider = new YjsProvider({
doc,
awareness,
baseUrl: 'https://api.electric-sql.cloud/v1/stream/svc-your-service',
docId: 'my-document',
})
```

Then wire it into your editor. Here's an example with&nbsp;TipTap:

```typescript
import { useEditor, EditorContent } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import Collaboration from '@tiptap/extension-collaboration'
import CollaborationCursor from '@tiptap/extension-collaboration-cursor'

const editor = useEditor({
extensions: [
StarterKit.configure({ history: false }),
Collaboration.configure({ document: doc }),
CollaborationCursor.configure({ provider }),
],
})
```

The provider handles sync, compaction, and awareness. Cursors, selections, and user presence work out of the box — every client that connects to the same `docId` sees the same document, in real&nbsp;time.

Clone the [demo&nbsp;app](https://github.com/durable-streams/durable-streams/tree/main/examples/yjs-demo) to see a working example, or drop the provider into your existing Yjs&nbsp;project.

## No lock-in

The Yjs Durable Streams protocol is [fully documented](https://github.com/durable-streams/durable-streams/blob/main/packages/y-durable-streams/YJS-PROTOCOL.md) with a conformance test suite — you can self-host, switch providers, or build your own compatible server at any&nbsp;time.

Electric Cloud implements the documented protocol strictly — no proprietary extensions, no vendor-specific APIs. It's just a faster way to get&nbsp;started.

## Next steps

- sign up to [Electric Cloud](https://dashboard.electric-sql.com)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the intent link.

- check the [example app](https://github.com/durable-streams/durable-streams/tree/main/examples/yjs-demo)
- any questions, let us know in [Discord](https://discord.electric-sql.com)
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
---
title: '...'
description: >-
...
excerpt: >-
...
authors: [balegas]
image: /img/blog/yjs-durable-streams-on-electric-cloud/header.jpg
tags: [durable-streams, cloud, release, sync, collaboration]
outline: [2, 3]
post: true
published: false
---

<!-- STRUCTURAL NOTE: This is a release post. Lead with what shipped and why
it matters. Factual, brisk, no preamble. Let the content do the work. -->

Yjs durable streams are now available on Electric Cloud. Real-time
collaborative editing as a managed service — sync Yjs documents over HTTP
instead of WebSockets.

Open protocol. Sub-50ms latency. Runs on the edge. Built-in compaction. No
infrastructure to manage. Create a service, point your Yjs app at it.

<!-- TONE: Compressed, confident. This paragraph IS the pitch.
Expand each line slightly into prose but keep it tight. -->

:::info
- [Create a Yjs service on Electric Cloud](https://github.com/durable-streams/durable-streams/tree/main/examples/yjs-demo)
- [`y-durable-streams` on GitHub](https://github.com/durable-streams/durable-streams/tree/main/packages/y-durable-streams)
- [Demo app](https://github.com/durable-streams/durable-streams/tree/main/examples/yjs-demo)
:::

## Context

<!-- STRUCTURAL NOTE: Brief orientation only. 2-3 bullets. Not a backstory —
just enough for readers who haven't been following durable streams. -->

- Durable Streams is an open HTTP protocol for persistent, resumable,
real-time streams. Append-only logs with their own URL that clients can
read from any position
- `y-durable-streams` is a Yjs provider that replaces WebSocket-based sync
with plain HTTP — works with standard load balancers and CDNs, no sticky
sessions
- Electric Cloud has been running durable streams services since January.
Yjs is the latest service type

## What's shipping

<!-- STRUCTURAL NOTE: Concrete capabilities. Lead with benefits,
follow with specifics. Each bullet = something the reader can now do. -->

- Managed Yjs sync on Electric Cloud — one click to create a service, get
an endpoint, connect your Yjs app
- Sub-50ms latency, edge-deployed, scales without you thinking about it
- Built-in server-side compaction — accumulated updates get merged into
snapshots automatically, initial loads stay fast as documents grow
- Awareness and presence out of the box — cursors, selections, user status
over the same HTTP transport
- Open protocol, no vendor lock-in — `y-durable-streams` works against any
durable streams server, self-hosted or cloud
- Just HTTP — no WebSocket servers, no sticky sessions, CDN-friendly

<!-- ASSET: demo video or GIF of collaborative editor with multiple cursors
and presence indicators -->

## Get started

<!-- STRUCTURAL NOTE: Show don't tell. The reader should be able to try it
from this section. One-click setup — keep it minimal. -->

<!-- AUTHOR NOTE: Include the direct link to create a Yjs service on Cloud.
This is a single click — don't over-explain the process. -->

- Link to create a Yjs durable streams service on Electric Cloud
- Clone the demo app and point it at your cloud endpoint:

```typescript
import { YjsProvider } from '@durable-streams/y-durable-streams'
import * as Y from 'yjs'

const doc = new Y.Doc()
const provider = new YjsProvider({
doc,
baseUrl: 'https://your-service.electric-sql.cloud/v1/yjs',
docId: 'my-document',
})
```

<!-- AUTHOR NOTE: Confirm the exact baseUrl pattern for cloud endpoints.
Mention it works with any Yjs editor binding — CodeMirror, ProseMirror,
TipTap, BlockNote, etc. -->

***

Next steps:

- [Sign up for Electric Cloud](https://dashboard.electric-sql.cloud/)
- [Try the demo](https://github.com/durable-streams/durable-streams/tree/main/examples/yjs-demo)
- [Join Discord](https://discord.electric-sql.com)

***

<!-- DELETE EVERYTHING BELOW THIS LINE BEFORE PUBLISHING -->

<!-- ## Meta

### Intent

- **What:** Yjs durable streams now available as a managed service on Electric Cloud
- **Hook:** Open protocol, sub-50ms latency, runs on the edge, built-in compaction, just HTTP — no WebSocket infrastructure
- **Takeaway:** Works with your existing stack, no vendor lock-in, cheap to run and scale
- **CTAs:** Sign up for Cloud, try the demo
- **Authority:** Electric team, experts in sync, background in CRDTs

### Title brief

Direction: Something direct and specific. "Yjs durable streams on Electric Cloud"
or "Real-time collaboration with Yjs on Electric Cloud". Sentence case, not Title
Case. Keep it short.

### Description brief

For SEO. Convey: managed Yjs sync service on Electric Cloud, HTTP-based (not
WebSocket), sub-50ms latency, open protocol, no vendor lock-in. Target developers
searching for Yjs hosting, Yjs sync, collaborative editing infrastructure.

### Excerpt brief

For the blog listing card. Max 3 short sentences. What shipped (Yjs durable
streams on Cloud), why it's interesting (HTTP, fast, open protocol), try it now.
Match word length of existing post excerpts.

### Image prompt

Abstract visualization of collaborative editing — multiple cursors or document
nodes connected over a network. Dark theme background. Electric brand colors:
purple (#D0BCFF), green (#00d2a0), cyan (#75fbfd). Center-center composition.
16:9 aspect ratio, ~1536x950px. High-quality JPG. Use /blog-image-brief for
a detailed prompt with reference analysis.

### Asset checklist

- [ ] Demo video or GIF: collaborative editor with multiple cursors and presence
- [ ] Code snippet: confirm exact cloud baseUrl pattern for YjsProvider
- [ ] Info box links: cloud dashboard URL, create-service link, demo repo link

### Typesetting checklist

- [ ] Use non-breaking spaces where appropriate to avoid widows and orphans
- [ ] Title uses sentence case, not Title Case
- [ ] Check title, image, and general post at different screen widths
- [ ] No LLM tells: "it's worth noting", "importantly", "in conclusion",
"let's dive in", "at its core", "in today's landscape"

### Open questions

- Exact URL pattern for cloud Yjs service endpoints
- Performance numbers beyond sub-50ms to include?
- Specific "coming next" items if any are decided later

-->
Loading
Loading