Skip to content

meslzy/wrpc

Repository files navigation

Wrpc

End-to-end type-safe WebSocket RPC framework for building real-time applications.

Documentation

Features

  • 🔒 Full Type Safety - Infer types from server to client automatically
  • 🏠 Room-Based Architecture - Isolated communication contexts with state management
  • Schema Validation - Runtime validation with Zod, Valibot, ArkType support
  • 🔄 Bidirectional Communication - Events, commands, and broadcasts
  • 📦 State Management - Built-in state sync with Immer patches
  • 🎣 Lifecycle Hooks - onCreate, onJoin, onLeave, onDispose
  • 🔑 Metadata System - Room-level and per-connection metadata
  • 🚀 Lightweight - Minimal dependencies, optimized for performance

Quick Example

Shared Definition

import { defineWrpc, defineWrpcRoom, defineWrpcRoomEvent } from "@wrpc/core";
import { z } from "zod";

const chat = defineWrpcRoom({
  state: z.object({
    messages: z.array(z.object({
      id: z.string(),
      sender: z.string(),
      content: z.string(),
    })),
  }),
  initialState: { messages: [] },
  create: z.object({ roomName: z.string() }),
  join: z.object({ userName: z.string() }),
  events: {
    sendMessage: defineWrpcRoomEvent({
      input: z.object({ content: z.string() }),
    }),
  },
});

export const wrpc = defineWrpc({ rooms: { chat } });

Server

import { createWrpcServer } from "@wrpc/server";

const wrpcServer = createWrpcServer(wrpc);

wrpcServer.rooms.chat({
  onJoin(context) {
    context.setState((draft) => {
      draft.messages.push({
        id: crypto.randomUUID(),
        sender: "System",
        content: `${context.input.userName} joined!`,
      });
    });
  },
  events: {
    sendMessage(context) {
      context.setState((draft) => {
        draft.messages.push({
          id: crypto.randomUUID(),
          sender: context.input.userName,
          content: context.input.content,
        });
      });
    },
  },
});

Client

import { createWrpcClient } from "@wrpc/client";

const client = createWrpcClient(wrpc, {
  url: "ws://localhost:5000/wrpc",
});

// Create and join room
const room = await client.rooms.chat.host({
  create: { roomName: "General" },
  join: { userName: "Alice" },
});

// Send event
room.sendEvent("sendMessage", { content: "Hello!" });

// Access state
console.log(room.state.messages);

Why Wrpc?

Feature Wrpc Socket.IO tRPC Colyseus
Bidirectional
Type Safety ✅ E2E ⚠️ Partial
Room System ⚠️ Manual
State Sync ✅ Built-in
Schema Validation ⚠️ Custom
Real-time First
Async Commands

License

MIT

About

End-to-end type-safe WebSocket framework with room-based architecture, built-in state management, and schema validation.

Topics

Resources

Stars

Watchers

Forks

Contributors