Skip to main content
npayload is launching soon.
npayloadDocs
SDKs

Browser SDK

Client-side SDK with real-time subscriptions, WebSocket, and E2E decryption

The @npayload/js SDK provides client-side access to npayload with real-time WebSocket subscriptions, automatic reconnection, and E2E decryption support.

Installation

npm install @npayload/js
pnpm add @npayload/js
yarn add @npayload/js
bun add @npayload/js

Quick start

import { NPayload } from '@npayload/js';

const npayload = new NPayload({
  publishableKey: 'pk_live_...',
});

// Subscribe to real-time messages
npayload.subscribe('orders', (message) => {
  console.log('New order:', message.payload);
});

Configuration

const npayload = new NPayload({
  publishableKey: 'pk_live_...',
  baseUrl: 'https://api.npayload.com',  // Custom API URL
  reconnect: {
    enabled: true,       // Auto-reconnect on disconnect
    maxAttempts: 10,     // Max reconnection attempts
    initialDelay: 1000,  // Start at 1s, exponential backoff
    maxDelay: 30000,     // Cap at 30s
  },
});

Authentication

Public key (read-only)

For client-side subscriptions where you only need to receive messages:

const npayload = new NPayload({
  publishableKey: 'pk_live_...',
});

User token (authenticated)

For client-side operations that require write access:

const npayload = new NPayload({
  getToken: async () => {
    const res = await fetch('/api/npayload-token');
    const { token } = await res.json();
    return token;
  },
});

Real-time subscriptions

Subscribe to a channel

const unsubscribe = npayload.subscribe('orders', (message) => {
  console.log('Event:', message.payload.event);
  console.log('Data:', message.payload);
});

// Unsubscribe when done
unsubscribe();

Filter by routing key

npayload.subscribe('orders', (message) => {
  console.log('Order created:', message.payload);
}, {
  routingKey: 'order.created',
});

Multiple channels

npayload.subscribe(['orders', 'notifications', 'alerts'], (message) => {
  console.log(`[${message.channel}]`, message.payload);
});

Connection events

npayload.on('connected', () => {
  console.log('Connected to npayload');
});

npayload.on('disconnected', (reason) => {
  console.log('Disconnected:', reason);
});

npayload.on('reconnecting', (attempt) => {
  console.log(`Reconnecting... attempt ${attempt}`);
});

npayload.on('error', (error) => {
  console.error('Connection error:', error);
});

Publishing messages

Requires authenticated access (user token, not public key).

await npayload.publish('events', {
  event: 'button.clicked',
  userId: 'user_123',
  timestamp: Date.now(),
});

E2E decryption

For channels using E2E privacy mode, provide your decryption key:

import { E2ECrypto } from '@npayload/js';

const crypto = new E2ECrypto({
  privateKey: userPrivateKey,
});

npayload.subscribe('secure-channel', (message) => {
  const decrypted = crypto.decrypt(message.payload);
  console.log('Decrypted:', decrypted);
});

Connection management

// Manual connect/disconnect
npayload.connect();
npayload.disconnect();

// Check connection state
console.log(npayload.isConnected); // boolean

Error handling

import { NPayloadAuthError, NPayloadNetworkError } from '@npayload/js';

try {
  await npayload.publish('events', { data: 'test' });
} catch (error) {
  if (error instanceof NPayloadAuthError) {
    // Token expired or invalid
  } else if (error instanceof NPayloadNetworkError) {
    // Network issue, will auto-retry if reconnect enabled
  }
}

TypeScript

Full type safety with generics:

interface OrderPayload {
  event: string;
  orderId: string;
  total: number;
}

npayload.subscribe<OrderPayload>('orders', (message) => {
  // message.payload is typed as OrderPayload
  console.log(message.payload.orderId);
});

Bundle size

ImportSize (gzipped)
Full SDK~8 KB
Core only (no crypto)~5 KB

Browser support

BrowserVersion
Chrome80+
Firefox78+
Safari14+
Edge80+

Next steps

Was this page helpful?

On this page