Getting started
chanx-js is the JavaScript side of chanx. It has two packages:
@chanx-js/client: the runtime. Zero dependencies and framework-agnostic, with optional bindings on@chanx-js/client/react,@chanx-js/client/vue,@chanx-js/client/svelteand@chanx-js/client/solid.@chanx-js/codegen: a CLI that turns a chanx AsyncAPI 3 schema into typed channel descriptors.
The server stays in Python: chanx-js only talks to it.
Install
pnpm add @chanx-js/client
pnpm add -D @chanx-js/codegennpm install @chanx-js/client
npm install -D @chanx-js/codegenyarn add @chanx-js/client
yarn add -D @chanx-js/codegenBoth packages are ESM only. The types need TypeScript 5.0 or later.
Generate a client
chanx serves its AsyncAPI schema over HTTP. Point the generator at it:
npx @chanx-js/codegen http://localhost:8000/asyncapi.json -o src/generatedThis writes three files:
| File | Contains |
|---|---|
schemas.ts | One type per message and payload in the schema |
channels.ts | A descriptor per channel, with topics nested under the connection they use |
index.ts | Re-exports both |
Commit the output and regenerate whenever the server's schema changes. See Code generation for every option, including JavaScript output and reusing types you already have.
Connect
import { createClient } from '@chanx-js/client';
import { chat } from './generated';
const client = createClient({ baseUrl: 'wss://api.example.com' });
const connection = client.connect(chat, { params: { room: 'lobby' } });
connection.on('chat_notification', (message) => {
console.log(message.payload.message); // narrowed by `action`
});
connection.send({ action: 'chat', payload: { message: 'hello' } });params is checked against the channel's address, so chat at /ws/chat/{room}/ requires room. Every message is typed from the schema: sending an action the server does not accept, or reading a field a message does not have, fails to compile.
In a component
import { useChannel } from '@chanx-js/client/react';
function ChatPanel({ room }: { room: string }) {
const { lastMessage, status, send } = useChannel(chat, { params: { room } });
// ...
}import { useChannel } from '@chanx-js/client/vue';
const { lastMessage, status, send } = useChannel(chat, { params: { room: 'lobby' } });import { createChannel } from '@chanx-js/client/svelte';
const channel = createChannel(chat, { params: { room: 'lobby' } });
// $channel.status, $channel.lastMessageimport { createChannel } from '@chanx-js/client/solid';
const channel = createChannel(chat, { params: { room: 'lobby' } });
// channel.status(), channel.lastMessage()Components on a channel that carries topics share one socket, which closes when the last of them unmounts. A plain channel gives each component its own socket unless you pass share: true; see Sharing and closing.
Next
- Connections: options, requests, reconnects and the heartbeat.
- Topics: many streams over one socket.
- Delivery modes:
lastMessage, accumulating buffers, and callbacks for hot streams. - Sharing and closing: how shared sockets behave, and how to close one for everyone.