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) |
---|---|---|
![]() |
![]() y-websocket server |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() y-protocols/awareness |
![]() |
![]() |
![]() |
![]() |
![]() lib0 , y-protocols libs |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() ypy-websocket exists but not production-ready |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
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
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