Skip to content

Blog: AI agents as CRDT peers — collaborative AI editor post#4093

Draft
samwillis wants to merge 10 commits intomainfrom
samwillis/blog-colab-editor
Draft

Blog: AI agents as CRDT peers — collaborative AI editor post#4093
samwillis wants to merge 10 commits intomainfrom
samwillis/blog-colab-editor

Conversation

@samwillis
Copy link
Copy Markdown
Contributor

@samwillis samwillis commented Apr 6, 2026

Preview: https://deploy-preview-4093--electric-next.netlify.app/blog/2026/04/08/building-a-collaborative-ai-editor

Summary

  • Outline for a blog post walking through how to build a collaborative AI editor using Durable Streams for both Yjs document sync and TanStack AI chat sessions
  • Pyramid principle format: situation (AI editing + collab + CRDTs) → complication (integration is painful, naive diff/patch breaks CRDTs) → answer (three streams one primitive, AI as CRDT peer, streaming edits, durable chat)
  • Header image generated ("twin cursors in a data stream")
  • published: false — outline only, needs prose-up

Next steps

  • Expand outline bullets into prose
  • Add code snippets from the collaborative-ai-editor repo
  • Record and embed demo video (YouTube)
  • Create architecture diagram
  • Capture screenshots/gifs of the editor in action
  • Fill in description and excerpt frontmatter
  • Review with /blog-review

Made with Cursor

Draft outline for a post walking through how to build a collaborative
AI editor using Durable Streams for both Yjs document sync and
TanStack AI chat sessions. Published: false.

Made-with: Cursor
- Fix CRDT streaming description (Yjs handles per-char fine)
- Expand document tools section with full search/place/edit flow
- Add software engineers angle to situation
- Add OT → CRDT evolution context
- Correct to three durable streams (doc, presence, chat)
- Reframe markdown as deliberate IR choice
- Simplify relative positions to focus on Yjs

Made-with: Cursor
- Fix tool names to match actual code (insert_text, set_format, etc.)
- Promote streaming edit routing to its own subsection
- Trim tool list to focus on read → locate → edit flow
- Add tech stack mention (TanStack Start, ProseMirror)
- Correct repo URL to electric-sql/collaborative-ai-editor
- Fix published: false
- Resolve open questions (YouTube, async tease, repo URL)

Made-with: Cursor
Title: "AI agents as CRDT peers: building a collaborative AI editor
with Yjs". Image brief with shared prompt and three "twin cursors in
a data stream" variations for ChatGPT DALL-E generation.

Made-with: Cursor
Generated "twin cursors in a data stream" header image and added
imageWidth/imageHeight to frontmatter.

Made-with: Cursor
@netlify
Copy link
Copy Markdown

netlify bot commented Apr 6, 2026

Deploy Preview for electric-next ready!

Name Link
🔨 Latest commit ac512a1
🔍 Latest deploy log https://app.netlify.com/projects/electric-next/deploys/69d429f91b3de00008b9f175
😎 Deploy Preview https://deploy-preview-4093--electric-next.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.


I've spent years in the collaborative editing space, it's how I discovered sync engines. Since AI agents became part of my daily workflow, I've had an ear worm: what would it look like to integrate an AI agent into a Yjs rich text editing flow — not as a sidebar that dumps text, but as a real participant with its own cursor, presence, and streaming edits?

This post walks through how I built a [Collaborative AI Editor](https://collaborative-ai-editor.examples.electric-sql.com) demo — a TanStack Start app with a ProseMirror/Yjs editor and an AI chat sidebar — using [Durable Streams](https://durablestreams.com) as the single transport layer for both [Yjs](https://yjs.dev) document collaboration and [TanStack AI](https://tanstack.com/ai) chat sessions. Two integrations, one primitive, and the AI becomes a genuine CRDT peer.
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.

Nice intro 🎯

This post walks through how I built a [Collaborative AI Editor](https://collaborative-ai-editor.examples.electric-sql.com) demo — a TanStack Start app with a ProseMirror/Yjs editor and an AI chat sidebar — using [Durable Streams](https://durablestreams.com) as the single transport layer for both [Yjs](https://yjs.dev) document collaboration and [TanStack AI](https://tanstack.com/ai) chat sessions. Two integrations, one primitive, and the AI becomes a genuine CRDT peer.

> [!Warning] Collaborative AI Editor demo
> Try the [live demo](https://collaborative-ai-editor.examples.electric-sql.com) and browse the [source code](https://github.com/electric-sql/collaborative-ai-editor).
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.

I know it adds noise but perhaps also links to docs for yjs and ts ai on the ds docs site?


- Try the [live demo](https://collaborative-ai-editor.examples.electric-sql.com) and browse the [source code](https://github.com/electric-sql/collaborative-ai-editor)
- Read the [Durable Streams + Yjs docs](https://durablestreams.com/yjs) and [Durable Streams + TanStack AI docs](https://durablestreams.com/tanstack-ai)
- Check out [Durable Streams Cloud](https://durablestreams.com) for hosted infrastructure
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.

yjs intent link?

excerpt: >-
...
authors: [samwillis]
image: /img/blog/building-a-collaborative-ai-editor/header.jpg
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.

Just with this image, I wonder if using more of the playful "elephant in a sandbox" / "durable sessions" reference images and having a more playful character editing could be an alternative approach? This image is a bit in the StreamDB / Transports vein which I think could perhaps be more for base primitives, whereas this is more application level, pulling things together?

Fill in description and excerpt, fix published flag, apply
non-breaking spaces consistently, tighten 'Why server-side matters'
overlap, fix typos (earworm, YjsProvider doubling), and simplify
the start_streaming_edit explanation.

Made-with: Cursor
…eholders

Add four code snippets verified against demo source: agent session
setup, document tool definitions, relative anchor encode/decode,
and durable chat connection. Add ASCII architecture diagram showing
three Durable Streams. Add visible blockquote placeholders for
remaining assets (video, screenshots, gifs).

Made-with: Cursor
…, rename to Apr 8

Replace ASCII diagram with SVG, add visible placeholder blocks for
video/screenshot assets, add cross-links to Yjs, TanStack AI,
ProseMirror, TanStack Start, Durable Streams integration docs, and
related blog posts. Rename post from April 6 to April 8.

Made-with: Cursor
…teps, remove planning meta

- Fix comma splice in conclusion, split long opening sentence
- Add async to createServerAgentSession snippet
- Rewrite conclusion to synthesize rather than restate
- Fix link text to match actual post title
- Vary repeated word choices, remove redundancy in markdown section
- Restructure Next Steps with hierarchy (Try / Learn / Build)
- Tighten Ink & Switch tangent, compress streaming markdown subsection
- Add inline CTAs linking to Cloud and source code
- Soften "survives everything" heading
- Set published: false, remove planning meta section

Made-with: Cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants