# Choosing the Right Backend for Collaboration Editor: Express vs FastAPI

**URL:** <https://forum.webuddhist.com/t/choosing-the-right-backend-for-collaboration-editor-express-vs-fastapi/209>\
**Category:** 🛠️ AI Tools WG\
**Tags:** frontend, rich-text-editor, docs, backend\
**Created:** [April 18, 2025, 6:05am UTC](https://forum.webuddhist.com/t/choosing-the-right-backend-for-collaboration-editor-express-vs-fastapi/209 "2025-04-18T06:05:13Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tenkus\_La](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.webuddhist.com/tenkus_la/32/41_2.png) [@Tenkus\_La](https://forum.webuddhist.com/u/Tenkus_La)\
**Post date:** [April 18, 2025, 6:05am UTC](https://forum.webuddhist.com/t/choosing-the-right-backend-for-collaboration-editor-express-vs-fastapi/209/1 "2025-04-18T06:05:13Z")

</div>

## 🧩 Context

When building a **real-time collaborative editor** (e.g., with Quill + Yjs or ProseMirror + Yjs), it’s crucial to select the right backend for handling synchronization, document state, and user awareness.

Two popular backend choices are:

- **Express.js (Node.js)**
- FastAPI (Python)

This guide compares both in the context of building a Yjs-powered collaboration server.

* * *

## ⚖ FastAPI vs Express: Side-by-Side Comparison

| Feature / Capability | **Express.js (Node.js)** | **FastAPI (Python)** |
| --- | --- | --- |
| 🔌 Native Yjs Support | ✅ Yes – with official [`y-websocket`](https://github.com/yjs/y-websocket) server | ❌ No – no official or stable Yjs WebSocket server |
| 🔄 Yjs Sync Protocol (Step 1,2,3) | ✅ Built-in support in JS ecosystem | ❌ Must be re-implemented manually |
| 👤 Awareness (User presence, cursors) | ✅ Supported via `y-protocols/awareness` | ❌ No support; must be ported from JS |
| ⚡ Binary WebSocket Messaging | ✅ Optimized & native in Node | ⚠ Supported in ASGI, but requires extra effort |
| 🧠 Use of `lib0`, `y-protocols` libs | ✅ Native in JS | ❌ No equivalent in Python |
| 💾 Realtime DB persistence (Prisma) | ✅ Easily integrated | ⚠ Requires API call to save Yjs state |
| 🧪 Experimental Yjs implementations | ❌ Not needed | ⚠ [`ypy-websocket`](https://github.com/yjs/ypy-websocket) exists but not production-ready |
| 🔁 State persistence performance | ✅ Direct access to database | ❌ Requires serialization and cross-service calls |
| 🌍 Community adoption and examples | ✅ Widely used in production | ❌ Very limited real-world examples |

* * *

## ⚠ Problem with Using FastAPI as a Separate Persistence Server

If you attempt to **separate the Yjs WebSocket server (Node.js)** and **FastAPI as a separate microservice** for saving state or metadata:

### You introduce:

- **⏱ Latency** from cross-service HTTP requests
- **❗ Risk of race conditions** between multiple simultaneous clients
- **⚠ Serialization overhead** when converting binary updates to JSON
- **🧱 Infrastructure complexity** (queues, retries, consistency checks)

Even if FastAPI is only used for saving state (e.g., `docs_y_doc_state` or `prosemirror_delta`), it will **increase response time** during document save, sync, or teardown.

> ❌ Therefore, for best performance, **you should NOT delegate Yjs state saving to FastAPI via API calls**.

* * *

There is an experimental project called [`ypy-websocket`](https://github.com/y-crdt/ypy-websocket) that attempts to replicate the Node.js WebSocket server in Python, but:

- It is **not production-ready**
- Lacks documentation, persistence, and extensibility
- Has very limited adoption and maintenance

## ✅ Final Recommendation

> **Stick with Express.js (Node.js) for your Yjs-based real-time collaboration backend.**  
> It offers the best performance, native protocol support, and minimal friction for building collaborative editors.

Let the Node.js Yjs server handle:

- WebSocket communication
- Document state synchronization
- Awareness (user presence, cursors)
- Database persistence (e.g., via Prisma)

* * *

## 🐍 Use FastAPI Where It Shines

FastAPI is still an **excellent companion service** , especially for:

- 🔐 Authentication and authorization (e.g., JWT, OAuth2)
- 🧑‍💼 User and project metadata
- 📊 Admin dashboards and analytics
- 🧰 Business logic and validation APIs

> ✅ Use FastAPI **alongside** your Node.js server — but not as a persistence layer for Yjs updates.

* * *

* * *

## 📌 Summary

- ✅ Node.js is the best environment for Yjs collaborative features
- ❌ FastAPI cannot replace Node.js for real-time document sync
- ⚠ Using FastAPI for saving Yjs state leads to latency and architectural complexity
- ✅ Use a **hybrid model** : Node.js for sync, FastAPI for metadata/auth

* * *

## 🔗 References

- [Yjs GitHub](https://github.com/yjs/yjs)
- [y-websocket](https://github.com/yjs/y-websocket)
- [FastAPI Docs](https://fastapi.tiangolo.com/)
- [ypy-websocket (experimental)](https://github.com/yjs/ypy-websocket)
- [lib0 – Binary utils for Yjs](https://github.com/dmonad/lib0)
