npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lupyd/light

v1.0.0

Published

Reliable WebRTC RPC and Datagrams library for Web, Node.js, and Bun

Readme

light ⚡

A lightweight, high-performance TypeScript library for reliable RPC calls and unreliable Datagrams over WebRTC. Works seamlessly across Browsers, Node.js, and Bun.


Key Features

  • 📦 Binary-First Protobuf Framing: All RPC messages, responses, and datagrams are encoded in compact binary Protocol Buffers (src/proto/protocol.proto). Supports raw Uint8Array payloads natively.
  • 🎯 Strict Type Safety: Fully inferred parameter and return types for RPC methods.
  • 🔄 Seamless Call Queuing: Calls made while connecting or reconnecting are queued automatically and transmitted once connected.
  • 🔁 Auto-Reconnection: Configurable retry logic (defaults to 3 retries) with automatic state recovery.
  • Low-Latency Datagrams: Unreliable topic-based messaging (maxRetransmits: 0) for real-time state updates (e.g. cursor positions, game loops).
  • 🌐 Cross-Environment WebRTC: Uses native browser WebRTC when available and falls back to werift in Node.js / Bun.
  • 🔌 Pluggable Signaling: Agnostic of signaling transport (WebSocket, WebSockets, broadcast channel, etc.).

Installation

pnpm add light
# or
bun add light

Quick Start

1. Define RPC Schemas

// Methods exposed by Peer A
export type PeerASchema = {
  getSystemInfo: () => { platform: string; uptime: number };
  calculateSum: (numbers: number[]) => number;
};

// Methods exposed by Peer B
export type PeerBSchema = {
  greetUser: (name: string) => string;
  processData: (input: { id: string; data: string }) => { processed: boolean; hash: string };
};

2. Instantiate and Connect Peers

Peer A (Initiator)

import { LightPeer } from 'light';
import type { PeerASchema, PeerBSchema } from './schema';

const peerA = new LightPeer<PeerASchema, PeerBSchema>({
  initiator: true,
  handlers: {
    getSystemInfo: () => ({ platform: process.platform, uptime: process.uptime() }),
    calculateSum: (numbers) => numbers.reduce((a, b) => a + b, 0),
  },
  autoReconnect: true,
  maxRetries: 3,
});

// Relay signaling data over your preferred signaling channel (e.g. WebSocket)
peerA.on('signal', (signal) => {
  signalingChannel.send({ to: 'peer-b', signal });
});

// Initiate connection
await peerA.connect();

Peer B (Receiver)

import { LightPeer } from 'light';
import type { PeerASchema, PeerBSchema } from './schema';

const peerB = new LightPeer<PeerBSchema, PeerASchema>({
  initiator: false,
  handlers: {
    greetUser: (name) => `Hello, ${name}!`,
    processData: (input) => ({ processed: true, hash: `hash_${input.id}` }),
  },
});

peerB.on('signal', (signal) => {
  signalingChannel.send({ to: 'peer-a', signal });
});

// Handle incoming signals from Peer A
signalingChannel.on('message', (data) => {
  peerB.handleSignal(data.signal);
});

Usage Guide

Making Typed RPC Calls

You can call remote methods directly. If the peer is still connecting or reconnecting, the call will be queued automatically and resolved once connection completes.

// Call Peer B's greetUser method from Peer A
const greeting = await peerA.call('greetUser', 'Alice');
console.log(greeting); // "Hello, Alice!"

// Type errors caught at compile-time!
// @ts-expect-error Invalid argument type
await peerA.call('greetUser', 123);

Unreliable Datagrams

For high-frequency or non-critical state updates, use datagrams.

// Subscribe to a topic
peerB.onDatagram('player_move', (payload, timestamp) => {
  console.log('Player moved to:', payload.x, payload.y);
});

// Send an unreliable datagram
peerA.sendDatagram('player_move', { x: 100, y: 250 });

Event Handling

peer.on('connectionStateChange', (state) => {
  console.log('Connection state:', state); // 'connecting' | 'connected' | 'failed' | 'closed'
});

peer.on('reconnecting', (attempt) => {
  console.warn(`Reconnecting attempt ${attempt}/3...`);
});

peer.on('reconnectFailed', () => {
  console.error('Failed to reconnect after maximum retries.');
});

peer.on('ready', () => {
  console.log('Data channels are open and ready for RPC calls.');
});

Running Included Examples

1. Interactive CLI Clients

Start the unified server, then run CLI client instances in separate terminal windows:

# Start unified web & signaling server
bun run example:web

# Terminal 1:
bun run example:cli cli-1 cli-2 true

# Terminal 2:
bun run example:cli cli-2 cli-1 false

Inside the CLI REPL:

  • call ping
  • call add 10 20
  • call echo "Hello"
  • datagram chat "Hey peer!"

2. Browser Client Example

bun run example:web

Open http://localhost:3000 in two browser tabs to interactively test WebRTC RPC calls, datagrams, and event logs.


Development & Testing

# Install dependencies
pnpm install

# Run typecheck & build
pnpm run build

# Run unit tests
pnpm run test

License

MIT