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

@rstreamlabs/tunnels

v3.1.0

Published

JS/TS SDK for the rstream Engine API and tunnel runtime APIs.

Readme

@rstreamlabs/tunnels

Engine HTTP API SDK for rstream tunnels.

Use this package when code needs operational tunnel state rather than the runtime tunnel protocol itself: list clients and tunnels, watch engine events, validate webhooks, mint scoped tunnel tokens, derive TURN credentials, and work with WebTTY tunnel metadata.

For hosted Control plane operations, use @rstreamlabs/rstream. For creating and serving bytestream tunnels from Node.js, use @rstreamlabs/runtime.

Install

npm install @rstreamlabs/tunnels

Client Setup

Connect directly to a known engine, which is the common self-hosted shape:

import { RstreamTunnelsClient } from "@rstreamlabs/tunnels";

const client = new RstreamTunnelsClient({
  credentials: { token: process.env.RSTREAM_AUTHENTICATION_TOKEN! },
  engine: process.env.RSTREAM_ENGINE!,
});

const tunnels = await client.tunnels.list();
const clients = await client.clients.list();

For hosted projects, provide projectEndpoint and let the SDK resolve the engine through the Control plane API:

import { RstreamTunnelsClient } from "@rstreamlabs/tunnels";

const client = new RstreamTunnelsClient({
  credentials: { token: process.env.RSTREAM_AUTHENTICATION_TOKEN! },
  projectEndpoint: "project-endpoint",
});

const engine = await client.getEngine();
const tunnels = await client.tunnels.list();

Application credentials are supported for backend integrations that should mint short-lived engine tokens on demand:

const client = new RstreamTunnelsClient({
  credentials: {
    clientId: process.env.RSTREAM_CLIENT_ID!,
    clientSecret: process.env.RSTREAM_CLIENT_SECRET!,
  },
  projectEndpoint: "project-endpoint",
});

const tunnels = await client.tunnels.list();

When application credentials are used with an explicit engine, also provide projectId or workspaceId so locally signed engine tokens are scoped.

Tunnel and Client Inventory

const tunnels = await client.tunnels.list({
  filters: {
    labels: {
      env: "prod",
    },
  },
});

const clients = await client.clients.list();

Schemas and TypeScript types are exported for clients, tunnels, stream summaries, and engine events.

Watch Streams

Watch subscribes to engine events over SSE or WebSocket and validates each event payload.

import { Watch } from "@rstreamlabs/tunnels";

const watch = new Watch(
  {
    auth: process.env.RSTREAM_AUTHENTICATION_TOKEN!,
    engine: process.env.RSTREAM_ENGINE!,
    transport: "sse",
  },
  {
    onEvent: (event) => {
      console.log(event.type);
    },
    onClose: () => {
      console.log("watch closed");
    },
  },
);

await watch.connect();

URL-based watch authentication requires a short-lived token with bounded lifetime and watch-only tunnel list resources.

Browser integrations should provide auth as a function that calls a backend token route and returns a fresh watch token for each connection attempt. Do not store the rstream.token query token as durable browser state.

Scoped Auth Tokens

auth.createAuthToken() mints short-lived engine tokens. Prefer resources.tunnels when delegating capabilities to devices, browser sessions, or other services.

const { token } = await client.auth.createAuthToken({
  expires_in: 60,
  resources: {
    tunnels: {
      scopes: {
        tunnels: {
          list: { select: { id: true, name: true, protocol: true } },
          connect: { params: { path: { regex: "^/api" } } },
        },
      },
    },
  },
});

When the client is configured with projectEndpoint or projectId, scope-only tunnel resources are project-scoped by default. Pass projectScoped: false only when a global scope-only tunnel resource is intentional.

TURN Credentials

The package supports the same TURN credential paths as the platform:

  • managed API issuance with a short-lived auth token
  • local derivation from a personal access token
  • local derivation from application credentials
import { createTURNCredentials } from "@rstreamlabs/tunnels";

const turn = await createTURNCredentials({
  credentials: {
    clientId: process.env.RSTREAM_CLIENT_ID!,
    clientSecret: process.env.RSTREAM_CLIENT_SECRET!,
  },
  projectEndpoint: "project-endpoint",
  clusterDomain: "cluster.example.rstream.test",
  ttlSeconds: 600,
});

TURN credentials are short-lived. ttlSeconds is optional, defaults to 600 for local derivation, and must be an integer between 1 and 3600 seconds. PAT-backed credentials are additionally capped by the PAT expiration.

Webhooks

Validate signed engine webhook payloads with constant-time signature comparison and schema parsing:

const event = await client.webhooks.event(
  rawBody,
  request.headers.get("rstream-signature")!,
  process.env.WEBHOOK_SECRET!,
);

console.log(event.type);

WebTTY Helpers

Use parseWebTTYServers() to derive WebTTY server metadata from tunnel inventory.

import { parseWebTTYServers } from "@rstreamlabs/tunnels";

const servers = parseWebTTYServers(await client.tunnels.list());

WebTTY server metadata includes advertised capabilities such as exec and fs. Older servers that do not advertise capabilities are treated as exec-only with the execution path /.

OpenAPI Document

The package exports the Engine API OpenAPI document from the main entrypoint and from the @rstreamlabs/tunnels/openapi subpath.

import { engineOpenApiDocument } from "@rstreamlabs/tunnels/openapi";

console.log(engineOpenApiDocument.info.title);

Environment Variables

| Variable | Purpose | | ------------------------------ | --------------------------------------------------------------- | | RSTREAM_API_URL | Control plane API URL used for managed project resolution. | | RSTREAM_ENGINE | Engine endpoint used when no engine is provided explicitly. | | RSTREAM_AUTHENTICATION_TOKEN | Bearer token used when credentials are not provided explicitly. |

Development

npm --workspace @rstreamlabs/tunnels run test
npm --workspace @rstreamlabs/tunnels run type-check
npm --workspace @rstreamlabs/tunnels run lint
npm --workspace @rstreamlabs/tunnels run build