Hocuspocus: a self-hosted Yjs WebSocket backend for real-time collaboration
The Yjs CRDT WebSocket backend for conflict-free real-time collaboration in your app.
At a glance
- What is it?
- Hocuspocus is a plug-and-play collaboration server built on Yjs CRDTs, written in TypeScript and published under the MIT licence. The README shows a server that fits in a dozen lines, but persistence, scaling and document lifecycle are the parts you have to think about yourself.
- Who is it for?
- Adopt Hocuspocus if you already use Yjs or a Yjs-based editor such as Tiptap, ProseMirror or Slate, and you want the sync server on your own infrastructure rather than a hosted service. Skip it if you need a document store with built-in history, search and permissions, because the README only describes the WebSocket layer and its extensions.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What problem Hocuspocus solves for Yjs users
Yjs gives you a CRDT document that merges concurrent edits without a central authority deciding who wins. What it does not give you is a place for those edits to meet. Two browsers editing the same document need a shared endpoint that accepts binary updates, rebroadcasts them to the other clients in the room, and optionally writes the merged state somewhere durable. That endpoint is what Hocuspocus provides. The README calls it "a plug & play collaboration backend based on Y.js", and the repository topics point at the same audience: collaborative-editing, crdt, prosemirror, slatejs, tiptap, self-hosted. If you are building an editor on top of Tiptap, ProseMirror or Slate and you have already decided on Yjs as the sync layer, Hocuspocus is the server half of that decision. It is not an editor, not a database and not a presence service in the sense of cursor avatars, though the hooks it exposes are where you would wire presence in.
How the server, documents and extensions fit together
The core object is a Server. You construct it with a configuration object and call listen(). Inside that configuration, extensions are the mechanism that turns a bare relay into something that persists or scales. The README's example pairs the server with the SQLite extension, which is a separate package, @hocuspocus/extension-sqlite, and takes a database path. The repository layout confirms this split: packages/ holds the individual modules, and the root docker-compose.yml defines exactly one service, redis:6-alpine on port 6379, which is the dependency the Redis extension would need. The playground directory contains separate entry points for the default setup, Express, Koa, Redis, webhooks, a slow variant and a load-document variant, so the intended integration surface is broader than the single README snippet suggests. The lifecycle is hook-driven. The README shows onConnect logging a crystal ball emoji, and the playground file names imply hooks such as loading a document and firing a webhook. That is the extension model: you do not subclass the server, you register callbacks and extensions and let the server call them at connect, load, store and disconnect time.
Installing Hocuspocus and running a first server
The README does not spell out an install command, but the package names are visible in its usage example and on npm: @hocuspocus/server for the server and @hocuspocus/extension-sqlite for persistence. The repository is a pnpm workspace, so pnpm is the package manager the maintainers use, though the published packages install with any client. A minimal server looks like the README's example, reproduced here with the same port, the same hook and the same extension options:
import { Server } from '@hocuspocus/server'
import { SQLite } from '@hocuspocus/extension-sqlite'
const server = new Server({
port: 1234,
async onConnect() {
console.log('đź”®')
},
extensions: [
new SQLite({
database: 'db.sqlite',
}),
],
});
server.listen();Running that file starts a WebSocket server bound to 127.0.0.1 on port 1234, or ws://127.0.0.1:1234 under the WebSocket protocol. When a client connects, the onConnect hook prints the emoji; when the SQLite extension is active, the document state is written to db.sqlite. To exercise the Redis path instead, the repository ships a compose file with a single service:
services:
redis:
image: "redis:6-alpine"
ports:
- "6379:6379"Bringing that up gives you Redis on 6379, which is the address the Redis playground expects. The repository also exposes Playwright-based end-to-end tests under tests/, run through ava with a 30 second timeout and worker threads disabled, so the test suite is a reasonable place to read for expected behaviour when the documentation is quiet.
Where Hocuspocus stops and you have to start
The README is short, and that is the honest limitation. It shows one server, one hook and one extension. It does not document rollback, conflict resolution policy, document garbage collection, per-document access control or rate limiting. Those are not oversights in the code so much as gaps in the front page: the full documentation lives at tiptap.dev/docs/hocuspocus/introduction, and the README points there rather than reproducing it. The practical consequence is that a naive deployment can be wrong in ways the README will not warn you about. A single process with the SQLite extension is fine for a demo and for small teams, but if you run two server instances behind a load balancer without the Redis extension, nothing in the README's example keeps the same document synchronised across those instances, and clients on different instances can diverge until a merge happens. Authorisation is also your problem. The onConnect hook is where the README puts a log line; in a real deployment that is where a token check belongs, and the README does not show one. If you need a document store with versioning, full-text search and permissions baked in, Hocuspocus is the wrong layer. It is a sync server, and the persistence extensions are deliberately thin.
Hocuspocus compared with Liveblocks and similar hosted sync services
The clearest alternative in this space is a hosted collaboration backend such as Liveblocks, where the sync server, presence and storage are operated for you and you integrate through their SDK. The difference is not just who runs the process. With Hocuspocus you own the WebSocket endpoint, the persistence database and the deployment topology, which means you also own the failure modes and the bill. In exchange you get to keep document data inside your own network, you get to choose the storage engine through extensions, and you can inspect the server because it is MIT licensed TypeScript in a public repository. The README itself acknowledges the hosting burden by pointing at Tiptap Collab as a cloud option for people who "don't want to care about hosting", which is a useful signal about where the maintainers see the friction. If your team has no one who wants to run a stateful WebSocket service, the hosted route removes a class of problems. If your constraint is data residency, custom persistence or a self-hosted-only policy, Hocuspocus is the one that lets you satisfy it.
Licence, maintenance and what an upgrade costs
The licence is MIT, stated in the README and in LICENSE.md, which permits commercial use and modification with the usual attribution requirement. That is a permissive position and it is worth noting because the same maintainers sell a hosted product, so the open source server and the commercial offering coexist rather than one gating the other. On maintenance, the repository is not archived, and the last push was on 2026-09-10, with releases at v4.7.0 on 2026-09-09, v4.6.0 on 2026-08-10 and v4.5.0 on 2026-08-04. The cadence is therefore regular, and the project is on a v4 line with a RELEASE_NOTES_V4.md at the repository root, which is where a major-version migration would be described. Upgrading within v4 is a package version bump in your own package.json, but the extensions are versioned separately, so a server upgrade and an extension upgrade are two decisions, not one. Budget for reading the release notes for both. The repository also carries a .coderabbit.yaml and a biome.json, so linting and review automation are configured in-tree; a contributor or a forker inherits those settings rather than choosing them.
Editorial conclusion
Adopt Hocuspocus if you already use Yjs or a Yjs-based editor such as Tiptap, ProseMirror or Slate, and you want the sync server on your own infrastructure rather than a hosted service. Skip it if you need a document store with built-in history, search and permissions, because the README only describes the WebSocket layer and its extensions. Before committing, verify three things: which persistence extension matches your database, whether the onConnect and onStoreDocument hooks cover your authorisation checks, and how the server behaves when the same document is opened on two instances without the Redis extension.
Frequently asked questions
When should I use Hocuspocus?
Use it when your editor already speaks Yjs and you want the WebSocket sync server on your own infrastructure, as the README describes a self-hosted backend with a configurable port and pluggable extensions. If you would rather not operate that service, the README points to Tiptap Collab as a hosted alternative.
How do I use Hocuspocus in a sentence?
The README gives the phrase in its own words: Hocuspocus is "a plug & play collaboration backend based on Y.js", so it names the server, not the client editor. The usage example then constructs a Server with port 1234 and calls listen().
What is Hocuspocus on?
It runs as a WebSocket server: the README's example listens on 127.0.0.1, or ws://127.0.0.1 under the WebSocket protocol, with port 1234 set in the configuration. The repository also ships a docker-compose.yml that runs redis:6-alpine on port 6379 for the Redis extension.
What does Hocuspocus mean here?
In this repository it is the name of the Yjs collaboration backend, not the phrase from folklore. The README describes it as based on Y.js, and the topics list yjs, crdt and collaborative-editing.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ueberdosis-hocuspocus)