API reference / @chanx-js/server
@chanx-js/server
Type-safe WebSocket server for TypeScript. Declare messages once: each action gets a validated, typed handler, groups broadcast across processes, and the whole API is documented as AsyncAPI, from which @chanx-js/codegen generates a typed client.
Runs on Node with ws, Express, Koa, Fastify, Hono, NestJS, Bun and Deno.
Documentation · Getting started · Why chanx-js? · API
bash
npm install @chanx-js/server ws zodts
import { createServer } from 'node:http';
import { z } from 'zod';
import {
PingMessage,
PongMessage,
consumer,
createChanx,
defineMessage,
} from '@chanx-js/server';
import { asyncapiMiddleware, attachChanx } from '@chanx-js/server/node';
const Chat = defineMessage('chat', z.object({ text: z.string() }));
const Notice = defineMessage('notice', z.object({ text: z.string() }));
const chat = consumer('/ws/chat/{room}', {
name: 'chat',
emits: [Notice],
groups: (conn) => [`room.${conn.params.room}`],
})
.on(PingMessage, { output: PongMessage }, () => PongMessage.create())
.on(Chat, (m, ctx) => ctx.broadcast(Notice.create({ text: m.payload.text })));
const chanx = createChanx({ consumers: [chat] });
const server = createServer(asyncapiMiddleware(chanx)); // docs at /asyncapi
attachChanx(server, chanx);
server.listen(8000);- Handlers, not if/else: payloads are validated by any Standard Schema library (Zod, Valibot, ArkType) before your handler runs.
- Groups and topics: broadcast to rooms, and let clients subscribe to many streams over one socket. Across processes with
@chanx-js/layers. - Runs anywhere: Node's
http, Express, Koa, Fastify, Hono, Bun, Deno, and NestJS. See integrations. - Testing: an in-process client and broadcast captures, from
@chanx-js/server/testing. - Compatible with Python chanx: same protocol, same AsyncAPI, one Redis shared by both.
MIT licensed.