
Teleportal is a library of tools, based on Y.js, that you add to your application to enable real-time collaborative editing like you see in Google Docs, Notion & Figma. It is meant to be a real-time collaborative editing framework, this is in distinction from a sync server, which typically works alongside your application, with it’s own storage, endpoints and APIs, rather than within your application.
To get a better understanding of how things work, take a look at this diagram:

In the diagram you’ll see:
- Clients connect to the server over a transport (e.g. WebSockets or HTTP + SSE)
- The server can enforce cross-document concerns like permissions & rate limiting
- Ultimately, the server’s main job is to propagate updates (between clients & servers, and persisting into the DB)
With Teleportal, all of this is built into your server, there isn’t a separate service to run, it is meant to scale with your application, re-use your storage, auth or anything else you need.

I want for Teleportal to become the de facto Y.js sync server; because, I believe it has properties that others do not. It can be:
- Run on any JS runtime, any storage solution, over any transport
- Built into & scales with your application
- End-to-end encryption (alpha) for secure document collaboration
One of the goals of Teleportal is to lower the barrier to entry for Y.js, it really isn’t approachable for the average developer and feels complex to implement. Teleportal makes Y.js easy to integrate into their existing application, avoiding the need to spin up separate servers and integrate with APIs to get what they need out of the system.
I will eventually put out a comparison across Y.js sync server’s to justify why I needed to build my own, but for now I’ll just list out some features that Teleportal has that I’ve not seen in other solutions:
- EE2E (alpha): Synchronize documents in real-time without the server knowing what the contents are
- Connection Fallback: If the client fails to establish a WebSocket connection, it will fallback to HTTP SSE for server-sent reads, and HTTP POST for client writes
- Developer Tools: Inspect every message sent over the connection (even if encrypted), see message and connection status
- Horizontal Scaling: Connect servers with a pub/sub system and they can scale horizontally instead of having to deal with fiddly WebSocket load-balancing
- RPC System: The protocol is extensible with your own message types, enables adding to the protocol things like:
- File Embeds: store files relative to a document, upload & download files over a streaming protocol on the same connection as your documents
- Document Versioning: Take snapshots of the document content at a point in time, to view progress over time
- Web-Native: Everything is built from the ground-up to be web-native JS, the server can even run on the client (not sure why you would do that, but it is possible!)
- Built-in Monitoring: Monitor the server with Prometheus metrics built-in, health checks & status
- And many more: Document multiplexing, sub-document support, message ACKs, offline persistence, etc.
The following code sets up a server with WebSockets & HTTP fallback, monitoring endpoints, and runs on any JS runtime:
import { serve } from "crossws/server";
import { getHTTPHandlers } from "teleportal/http";
import { Server } from "teleportal/server";
import { YDocStorage } from "teleportal/storage";
import { getWebsocketHandlers } from "teleportal/websocket-server";
const server = new Server({
storage: new YDocStorage(),
});
serve({
websocket: getWebsocketHandlers({
server,
onUpgrade: async () => {
return {
context: { userId: "nick", room: "test" },
};
},
}),
fetch: getHTTPHandlers({
server,
getContext: () => {
return { userId: "nick", room: "test" };
},
fetch: async () => {
const res = await fetch(
"https://raw.githubusercontent.com/nperez0111/teleportal/refs/heads/main/examples/simple/index.html",
);
return new Response(await res.text(), {
headers: { "Content-Type": "text/html" },
});
},
}),
});
Reach out to the @Teleportalaccount on Bluesky & comment here:
