π Inspired by trpc π yjs π
and Cloudflare Workers π
pluv.io allows you to more easily build realtime multiplayer experiences with a fully typesafe API and powerful abstractions as primitives, so that you can focus on building for your end users.
Self-host on Cloudflare Workers or Node.js; or get started on the pluv.io network.
Create your pluv.io backend
// backend
const io = createIO(
platformNode({
context: () => ({ db }),
crdt: yjs,
})
);
export const ioServer = io.server({
getInitialStorage: async ({ context: { db }, room }) => {
return await db.room
.findUnique({ where: { id: room } })
.then((result) => result?.encodedState ?? null);
},
router: io.router({
sendGreeting: io.procedure
.input(z.object({ message: z.string() }))
.broadcast(({ message }) => ({
receiveGreeting: { message }
}))
})
});
Create your frontend client with your backend types
// frontend
const types = infer((i) => ({ io: i<typeof ioServer> }));
const io = createClient({
types,
initialStorage: yjs.doc((t) => ({
messages: t.array<string>("messages"),
})),
presence: z.object({
selectionId: z.string().nullable()
})
});
const {
event,
useBroadcast,
useMyPresence,
useOthers,
useStorage
} = createBundle(io);
Use powerful primitives to build realtime features
// react
event.receiveGreeting.useEvent(({ data }) => { /* ... */});
// ^? const data: { message: string }
const broadcast = useBroadcast();
broadcast.sendGreeting({ message: "hello world" });
// ^? const sendGreeting: (data: { message: string }) => void
const [mySelection, update] = useMyPresence((presence) => {
// ^? const mySelection: string | null
return presence.selectionId;
});
const others = useOthers((others) => {
// ^? const others = string[]
return others.map((other) => other.presence.selectionId);
});
const [
messages,
// ^? const messages: string[] | null
sharedType
// ^? YArray<string> | null
] = useStorage("messages");
The full documentation is available at pluv.io.
- β Automatic type-safety
- β Basic events
- β Rooms
- β Authentication
- β Awareness + Presence
- β
CRDTs
- β
Yjs
- β Provider
- β
Shared Types
- β Map
- β Array
- β Text
- β XmlFragment
- β XmlElement
- β XmlText
- β
Loro (preview)
- β
Containers
- β Counter
- β List
- β Map
- β Moveable List
- β Text
- β Tree
- β
Containers
- β
Yjs
- β¬ Studio (admin & developer panel)
- β
Cloudflare Workers
- WebSocket API
- β Hibernation API (default, recommended)
- β Standard API
- State Persistence
- β SQLite-backed Durable Objects (default, recommended)
- β Key-value storage-backed Durable Object
- WebSocket API
- β Node.js
- @pluv/io - Server
- @pluv/client - Framework agnostic client
- @pluv/react - Integrate @pluv/client with React.js
- @pluv/platform-pluv - Adapter to run on pluv.io
- @pluv/platform-cloudflare - Adapter to run on Cloudflare Workers
- @pluv/platform-node - Adapter to run on Node.js
- @pluv/crdt-yjs - Yjs CRDT adapter
- @pluv/crdt-loro - Loro CRDT adapter
- @pluv/persistence-redis - Persistence for storage on distributed systems (Node.js only)
- @pluv/persistence-cloudflare-transactional-storage - Durable Object persistent state for WebSocket hibernation
- @pluv/pubsub-redis - PubSub for rooms across distributed systems
This software uses the following open source tooling and libraries: