@levelchat/web
v0.2.5
Published
LevelChat Web SDK — WebRTC rooms, live streams, recording, chat, and E2EE in one tree-shakeable library.
Downloads
337
Maintainers
Readme
@levelchat/web
Production-grade LevelChat Web SDK. WebRTC rooms, live streams, recording, chat, and end-to-end encryption in one tree-shakeable TypeScript library.
Install
npm install @levelchat/web
# or
pnpm add @levelchat/web
yarn add @levelchat/webWe follow semver; pin major. Latest version: 0.2.x (update on release).
Hello room
import { LevelChat } from '@levelchat/web';
// Token comes from YOUR backend (POST /v1/rooms/:id/tokens with your project key).
const { token, url } = await fetch('/api/lc-token?room=r_demo').then((r) => r.json());
const lc = new LevelChat({ logLevel: 'info' });
const live = await lc.joinLive({ token, signalingUrl: url, roomType: 'meeting' });
await live.publishCamera({ resolution: '720p' });
await live.publishMic();
live.room.on('track-subscribed', (t) => {
if (!t.mediaStreamTrack) return;
const el = document.createElement('video');
el.srcObject = new MediaStream([t.mediaStreamTrack]);
el.autoplay = true;
el.playsInline = true;
document.body.appendChild(el);
});Quickstart
import { LevelChat } from '@levelchat/web';
// In production the token comes from YOUR BACKEND; never expose an API key in the browser.
const token = await fetch('/api/levelchat/token').then((r) => r.text());
const client = new LevelChat({ region: 'eu-fsn', logLevel: 'info' });
const room = await client.joinRoom({ token });
await room.publishCamera({ resolution: '720p' });
await room.publishMic();
room.on('participant-joined', (p) => console.log('hello', p.displayName));
room.on('track-subscribed', (t) => attachToVideoElement(t.mediaStreamTrack));
room.on('connection-quality', (id, q) => console.log(id, q.label));What you get
- Single class surface —
LevelChat,Room,NetworkQualityScorer,DeviceManager, typed errors, typed events. - Codec-aware publishing — simulcast for H.264/VP8, SVC (
L3T3_KEY) for VP9/AV1. - Transport-cc bandwidth adaptation — handled automatically against libwebrtc's GCC.
- Perfect-negotiation SDP — no more glare races.
- Automatic reconnect — 250 ms → 8 s exponential backoff with jitter, ICE restart on resume.
- Device hot-swap —
DeviceManagerwrapsnavigator.mediaDeviceswith change notifications. - Insertable-stream E2EE — SFrame-style header + AES-GCM body; bring your own MLS group key.
- Headless entry point —
@levelchat/web/headlessfor bots, SSR, and tests. - RNNoise hook —
@levelchat/web/noise-suppressionlazy-loads the WASM worklet.
Bundle size
Built output is under 30 KB gzip for the core @levelchat/web entry point (measured via pnpm run size). Bring-your-own zod if you already ship it.
Events
room.on('participant-joined' | 'participant-left', (p) => …);
room.on('track-published' | 'track-unpublished' | 'track-subscribed', (t) => …);
room.on('connection-quality', (id, q) => …);
room.on('connection-state', (s) => …);
room.on('active-speaker', (id, level) => …);
room.on('recording-started' | 'recording-stopped', (r) => …);
room.on('chat-message', (m) => …);
room.on('reaction', (r) => …);
room.on('error', (e) => …);All platform SDKs emit the same event names — see docs/api/02-sdk-parity.md.
Development
pnpm install
pnpm --filter @levelchat/web build
pnpm --filter @levelchat/web testMIT licensed.
See also
- docs/architecture/05-api-surface.md — REST + SDK API contract
- docs/architecture/03-video-stack.md — SFU and E2EE architecture
- packages/sdk-web-react/README.md — React bindings
- packages/shared-types/ — shared TypeScript types
- DEMO.md — live broadcaster/viewer demo using this SDK
