Docs/Client SDKs/JavaScript SDK

JavaScript SDK

@emitwave/js — the browser client for connecting, subscribing to channels, and receiving realtime events.

Client SDK· 6 min read

Install

bash
npm install @emitwave/js

Requires a modern browser with fetch, WebSocket, and Web Crypto. You need a public application key and an end-user Bearer token — never put a server secret in browser code.

Connect & subscribe

connect() starts the socket handshake and is required for every connection, including public-only ones. The authHeaders callback runs before each token request, so a refreshed token is used without recreating the client.

client.ts
import { Emitwave } from '@emitwave/js'

const emitwave = new Emitwave('ew_pk_live_your_public_key', {
  authHeaders: async () => ({
    Authorization: `Bearer ${await getEndUserToken()}`,
  }),
})

await emitwave.connect()

const channel = await emitwave.subscribe('news')
channel.bind('article.created', (article) => console.log(article))
channel.bindAll((event, data) => console.log(event, data))

Defaults target production — the EmitWave WebSocket and the connect-token / channel-auth endpoints. Override wsUrl, connectEndpoint, and authEndpoint only when targeting another environment.

Connection state

state.ts
emitwave.onState((state) => {
  // 'connecting' | 'connected' | 'disconnected' | 'error'
  console.log('connection:', state)
})

Channel types

The same subscribe() call handles every external channel name; the prefix determines authorization. See Channels for the full table.

ExampleChannel auth
newsNo
private-account.42Yes — truthy callback
presence-room.lobbyYes — returns { id, info }
private-encrypted-account.42Yes — plus per-channel key

Presence

The members property is only available on presence channels.

presence.ts
const room = await emitwave.subscribe('presence-room.lobby')

room.members.each((m) => console.log(m.id, m.info))
console.log(room.members.count, room.members.me)

room.member_added((m) => console.log('joined', m))
room.member_removed((m) => console.log('left', m))

Cache & encryption

cache_miss and decryption_error are reserved SDK events and are not passed to bindAll().

reserved.ts
channel.bind('cache_miss', () => {
  // Fetch initial state from your HTTP API
})

channel.bind('decryption_error', () => {
  // Encrypted payload could not be decrypted
})
Client-originated events are not enabled. Publish events from a trusted server with one of the server SDKs.

Cleanup

cleanup.ts
channel.unbind('article.created', handler)
emitwave.unsubscribe('news')
emitwave.disconnect()