@sockudo/client
v2.1.0
Published
Sockudo JavaScript client full port on Bun + Oxc + Vite 8
Downloads
36,115
Maintainers
Readme
@sockudo/client
Sockudo JavaScript client SDK with modern runtime targets:
- Web
- Node.js
- Web Worker
- React hooks
- Vue composables
- React Native
- NativeScript
Install
For apps, install the published package:
npm install @sockudo/client
# or: bun add @sockudo/client
# or: pnpm add @sockudo/clientFor contributors working inside this repository, build the SDK from its package directory:
cd client-sdks/sockudo-js
bun install
bun run build:allRuntime Imports
Use the entrypoint that matches your runtime:
// Browser / default
import Sockudo from "@sockudo/client";
// Filter helper entrypoint
import { Filter } from "@sockudo/client/filter";
// With encryption
import SockudoEncrypted from "@sockudo/client/with-encryption";
// Worker
import WorkerSockudo from "@sockudo/client/worker";
// Worker with encryption
import WorkerEncrypted from "@sockudo/client/worker/with-encryption";
// React hooks
import { SockudoProvider, useChannel } from "@sockudo/client/react";
// Vue composables
import { createSockudoPlugin, useChannel as useSockudoChannel } from "@sockudo/client/vue";
// React Native
import ReactNativeSockudo from "@sockudo/client/react-native";
// NativeScript
import NativeScriptSockudo from "@sockudo/client/nativescript";The package also exposes runtime-aware fields in package.json (main, browser, react-native, nativescript, exports) so bundlers can resolve correctly.
Quick Start
import Sockudo from "@sockudo/client";
const sockudo = new Sockudo("app-key", {
wsHost: "your-sockudo-host",
wsPort: 6001,
wssPort: 6001,
forceTLS: true,
enabledTransports: ["ws", "wss"],
});
const channel = sockudo.subscribe("public-updates");
channel.bind("message", (payload: unknown) => {
console.log(payload);
});The default client mode is Protocol V1 compatibility (protocol=7). Opt into Protocol V2 explicitly when you want Sockudo-native event prefixes and V2-only features.
const sockudoV2 = new Sockudo("app-key", {
wsHost: "your-sockudo-host",
wsPort: 6001,
forceTLS: true,
protocolVersion: 2,
});Protocol V2 heartbeat behavior:
- the server uses native WebSocket ping/pong frames for automatic liveness
- browser-style runtimes that do not expose native ping APIs may still use lightweight
sockudo:ping/sockudo:pongfallback messages for client-side activity checks - fallback heartbeat messages are not part of V2 broadcast continuity and do not carry
message_id,serial, orstream_id
Features
- Pusher-protocol-compatible client surface
- Protocol V1 compatibility by default
- WebSocket-first connection strategy
- Fetch-first auth/timeline integrations
- ESM-first package outputs
- Runtime-specific builds for web/node/worker/react-native/nativescript
- Built-in React hooks via
@sockudo/client/react - Built-in Vue composables via
@sockudo/client/vue - Continuity-aware recovery positions and subscribe-time rewind in Protocol V2
Recovery And Rewind
const client = new Sockudo("app-key", {
wsHost: "127.0.0.1",
wsPort: 6001,
forceTLS: false,
protocolVersion: 2,
connectionRecovery: true,
});
const channel = client.subscribe("market:BTC", {
rewind: { seconds: 30 },
});
channel.bind("message", () => {
console.log(client.getRecoveryPosition("market:BTC"));
});
client.bind("sockudo:resume_success", (payload) => {
console.log(payload.recovered, payload.failed);
});
channel.bind("sockudo:rewind_complete", (payload) => {
console.log(payload.historical_count, payload.complete);
});Mutable Messages (Release 4.3)
Protocol V2 mutable messages use explicit action events:
sockudo:message.updatesockudo:message.deletesockudo:message.append
Client interpretation rules:
message.update: replace local state with the full payload in the eventmessage.delete: treat the event as the latest visible version; the payload may benullmessage.append: concatenate the incoming string fragment onto your current local string state
If you do not already have a string base for message.append, fetch the latest visible message first and seed local state before applying more appends.
The JS SDK exports helpers for this:
import Sockudo, {
isMutableMessageEvent,
reduceMutableMessageEvent,
type MutableMessageState,
} from "@sockudo/client";
const client = new Sockudo("app-key", {
wsHost: "127.0.0.1",
wsPort: 6001,
forceTLS: false,
protocolVersion: 2,
});
let state: MutableMessageState | null = null;
client.subscribe("chat:room-1").bind_global((eventName, payload) => {
if (!isMutableMessageEvent(payload)) {
return;
}
state = reduceMutableMessageEvent(state, payload);
console.log(state?.messageSerial, state?.action, state?.data);
});Version-history consumption:
- consume
GET /apps/{appId}/channels/{channelName}/messages/{messageSerial}when you need the latest visible state - consume
GET /apps/{appId}/channels/{channelName}/messages/{messageSerial}/versionswhen you need preserved historical versions - process versions in
version_serialorder; the last version is the winning visible state
Proxy-backed read helpers:
Configure versionedMessages.endpoint when you want first-class helper methods without exposing server credentials in the client. The endpoint should accept a JSON POST body of the form { channel, messageSerial?, params?, action } and proxy the request to Sockudo's REST API using server-side HMAC auth.
const client = new Sockudo("app-key", {
cluster: "local",
wsHost: "127.0.0.1",
wsPort: 6001,
forceTLS: false,
versionedMessages: {
endpoint: "/sockudo/versioned",
},
});
const channel = client.subscribe("chat:room-1");
const latest = await channel.getMessage("message-serial");
const versions = await channel.getMessageVersions("message-serial", {
limit: 20,
direction: "oldest_first",
});
const history = await channel.channelHistory({
limit: 50,
direction: "newest_first",
});React Hooks
Install the framework peer dependencies:
npm install @sockudo/client react react-domimport React from "react";
import Sockudo from "@sockudo/client";
import { SockudoProvider, useChannel } from "@sockudo/client/react";
const client = new Sockudo("app-key", {
wsHost: "127.0.0.1",
wsPort: 6001,
forceTLS: false,
});
client.connect();
function PresencePanel() {
const { subscribed, members } = useChannel("presence-room");
return (
<div>
<div>Subscribed: {String(subscribed)}</div>
<div>Members: {members?.length ?? 0}</div>
</div>
);
}
export function App() {
return (
<SockudoProvider client={client}>
<PresencePanel />
</SockudoProvider>
);
}Available React exports:
SockudoProvideruseSockudouseSockudoEventuseChannelusePresenceChannel
Vue Composables
Install the framework peer dependency:
npm install @sockudo/client vueimport { createApp, defineComponent, h } from "vue";
import Sockudo from "@sockudo/client";
import { createSockudoPlugin, useChannel } from "@sockudo/client/vue";
const client = new Sockudo("app-key", {
wsHost: "127.0.0.1",
wsPort: 6001,
forceTLS: false,
});
client.connect();
const PresencePanel = defineComponent({
setup() {
const { subscribed, members } = useChannel("presence-room");
return () =>
h("div", [
h("div", `Subscribed: ${String(subscribed.value)}`),
h("div", `Members: ${members.value?.length ?? 0}`),
]);
},
});
createApp(PresencePanel).use(createSockudoPlugin(client)).mount("#app");Available Vue exports:
createSockudoPluginprovideSockudouseSockudouseSockudoEventuseChannelusePresenceChannel
React Native Notes
- React Native build output is
dist/react-native/sockudo.js - Package exposes both:
- root
react-nativeresolution - explicit
@sockudo/client/react-nativesubpath
- root
@react-native-community/netinfois an optional peer dependency- React Native support remains inside
@sockudo/client; React and Vue integrations stay as subpath exports in the same package
NativeScript Notes
- Install the NativeScript websocket polyfill:
npm install @sockudo/client @valor/nativescript-websockets- Import
@sockudo/client/nativescriptto automatically load the websocket polyfill before the SDK. - NativeScript build output is
dist/nativescript/sockudo.js - Package exposes both:
- root
nativescriptresolution - explicit
@sockudo/client/nativescriptsubpath
- root
Development
Requirements
- Bun
>=1.0.0 - Node.js
>=22
Commands
# typecheck + lint + tests
bun run check
# typecheck only
bun run typecheck
# lint
bun run lint
# format
bun run format
bun run format:check
# tests
bun test
bun run test:watch
# builds
bun run build
bun run build:allRelease Process
GitHub Actions are managed from the monorepo root:
- CI:
.github/workflows/sdk-ci.yml - Publish:
.github/workflows/sdk-release.ymlwith tagclient-js-vX.Y.Z - Setup: see
docs/sdk-publishing-2026.mdfor npm trusted publishing and provenance.
The release gate runs format checks, type checks, linting, tests, build:all, and npm pack
--dry-run before publishing.
Repository
- Source:
https://github.com/sockudo/sockudo/tree/main/client-sdks/sockudo-js - Legacy repo:
https://github.com/sockudo/sockudo-js(archived) - npm:
https://www.npmjs.com/package/@sockudo/client
