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

@rumtrace/web-sdk

v0.5.0

Published

Browser RUM SDK built on OpenTelemetry JS.

Readme

@rumtrace/web-sdk

Browser Real User Monitoring SDK built on the official OpenTelemetry JavaScript packages.

The SDK exposes one primary entry point:

import rumtrace from '@rumtrace/web-sdk';

const rum = rumtrace.start('my web app', 'public-collector-token', {
  collectorUrl: 'https://ingest.rumtrace.com/',
  environment: 'production',
  release: '1.2.3',
  country: 'TR'
});

It sends OTLP/HTTP protobuf telemetry to:

  • <collectorUrl>/v1/traces
  • <collectorUrl>/v1/logs

Install

npm install @rumtrace/web-sdk

Optional router integrations use peer dependencies from the host app:

npm install react
npm install next react
npm install react-router

OpenTelemetry Usage

This package consumes OpenTelemetry JS for providers, browser auto-instrumentation, batching, and OTLP protobuf serialization while keeping a small SDK-owned HTTP exporter for browser-specific delivery behavior.

  • Providers: WebTracerProvider, LoggerProvider
  • Serialization: @opentelemetry/otlp-transformer
  • Export: SDK HttpTelemetryExporter with retry, gzip support, unload delivery, and offline queue replay
  • Batching: BatchSpanProcessor, BatchLogRecordProcessor
  • OpenTelemetry auto instrumentation: document load, fetch, XHR
  • SDK custom instrumentation: route changes, browser errors, interactions, Web Vitals, resource timing
  • Resource creation: resourceFromAttributes

SDK-owned code focuses on the RUM facade, session/user attributes, error isolation, redaction, route helpers, browser error capture, web vitals, resource timing, and offline queue persistence. Web Vitals are emitted as log records with webvital.* attributes, not OTLP metrics.

Basic Usage

import { start } from '@rumtrace/web-sdk';

const rum = start('checkout-web', 'public-collector-token', {
  collectorUrl: 'https://ingest.rumtrace.com/',
  headers: {
    'x-org-id': 'org_123'
  },
  sampleRate: 1,
  country: 'TR',
  websiteVersion: '2026.05.16',
  user: {
    id: 'user-123',
    attributes: { plan: 'pro' }
  },
  enabledInstrumentations: [
    'page-load',
    'route-change',
    'network',
    'error',
    'interaction',
    'web-vitals',
    'resource-timing'
  ]
});

rum.log.info('checkout loaded', { cart_items: 3 });

const span = rum.startSpan('apply coupon');
span.setAttribute('coupon.code', 'SUMMER');
span.end();

Options

| Option | Default | Description | | --- | --- | --- | | collectorUrl | https://ingest.rumtrace.com/ | HTTPS OTLP base URL. Non-HTTPS URLs return a no-op instance. | | headers | {} | Extra exporter headers. A provided Authorization header overrides the bearer token. | | sampleRate | 1 | Session sampling rate from 0 to 1. Invalid values fall back to 1. | | environment | undefined | Resource attribute deployment.environment. | | release | undefined | Resource attribute service.version. | | websiteVersion | undefined | Alias for service.version when release is omitted. | | country | undefined | User country code, emitted as geo.country.iso_code. Two-letter codes are uppercased. | | user | undefined | Initial user. Pass a string user id or { id, attributes }; maps to enduser.id and enduser.*. | | enabledInstrumentations | core browser instrumentations | Limits which instrumentations are registered. | | ignoreUrls | [] | String or RegExp URL matchers excluded from fetch and XHR network instrumentation. The collector URL is always ignored. | | propagateTraceHeaders | false | Enables trace header propagation for allowed network destinations. | | propagateTraceHeadersAllowList | [] | String or RegExp URL allow-list for propagation. String entries match exact origins or URL path prefixes after new URL(entry, location.href) normalization. | | captureBodies | false | Reserved for network body capture. Bodies are not captured by default. | | payloadCompression | 'gzip' | Gzip-compresses OTLP protobuf request bodies when the browser supports CompressionStream. Set to 'none' to send plain protobuf bytes. | | redact.urlQueryKeys | built-in sensitive list | Additional query-string keys to redact. | | beforeSendBatch | undefined | Receives encoded batch metadata { kind, size }; return false to drop the batch. |

beforeSendBatch runs after OTLP encoding, so it cannot mutate individual telemetry records.

Compressed batches are sent with Content-Encoding: gzip. Configure the collector or proxy in front of it to accept gzip-encoded OTLP/HTTP requests.

RegExp entries in propagateTraceHeadersAllowList are used as provided and can match any URL, so treat them as user-owned propagation policy.

Automatic Context

The SDK adds session, user, page, browser, device, OS, display, language, country, and version context to SDK-owned telemetry. Web Vitals are emitted as log records and include the same context, so LCP, INP, CLS, FCP, and TTFB can be grouped by these fields.

| Attribute | Source | | --- | --- | | session.id, session.sampled | SDK session manager. | | enduser.id, enduser.* | options.user and rum.setUser(). | | service.version | options.release or options.websiteVersion. | | deployment.environment | options.environment. | | geo.country.iso_code | options.country. | | browser.name, browser.version | User agent detection. | | browser.language | navigator.language or first navigator.languages entry. | | device.type, device.model | User agent detection. | | os.name, os.version | User agent detection. | | page.title | document.title. | | page.referrer | document.referrer, with query redaction. | | screen.width, screen.height | screen.width and screen.height. | | screen.avail_width, screen.avail_height | screen.availWidth and screen.availHeight. | | viewport.width, viewport.height | window.innerWidth and window.innerHeight. |

Web Vital logs also include webvital.name, webvital.value, webvital.unit, webvital.rating, webvital.delta, webvital.id, and, when available, webvital.navigation_type.

Browser error logs include error.fingerprint, a deterministic hash built from the redacted error type, message, source location, and stack. The SDK uses the same fingerprint to debounce matching errors within the one-second error aggregation window.

Public API

interface RumInstance {
  log: LogApi;
  startSpan(name: string, attributes?: Attributes): SpanHandle;
  addEvent(name: string, attributes?: Attributes): void;
  setGlobalAttribute(key: string, value: AttributeValue): void;
  removeGlobalAttribute(key: string): void;
  setUser(userId: string, attributes?: Attributes): void;
  clearUser(): void;
  flush(): Promise<void>;
  shutdown(): Promise<void>;
}

Router Adapters

React Router:

import { trackReactRouterNavigation } from '@rumtrace/web-sdk/react-router';

trackReactRouterNavigation(rum, '/products/:id', { id: '123' });

Next.js Pages Router:

import { enableNextPagesRouter } from '@rumtrace/web-sdk/next-pages-router';

const disable = await enableNextPagesRouter(rum, {
  redact: { urlQueryKeys: ['session_id'] }
});

Next.js App Router:

import { trackNextAppNavigation } from '@rumtrace/web-sdk/next-app-router';

trackNextAppNavigation(rum, {
  pathname: '/products/123',
  pattern: '/products/[id]',
  redact: { urlQueryKeys: ['session_id'] }
});

Error Isolation

All public SDK methods and custom browser callbacks are wrapped by ErrorIsolator. Internal failures are caught, rate-limited to one console warning per signature per 60 seconds, and converted to no-op behavior where possible.

Invalid initialization arguments return a no-op RumInstance, so host application code can keep calling the SDK without defensive checks.

Redaction

http.url query parameters are redacted when their key is one of:

  • password
  • token
  • secret
  • api_key
  • authorization
  • any key in options.redact.urlQueryKeys

Route, resource, network, router-adapter, and page.referrer URL attributes use the same query redaction policy. Browser error messages are truncated to 1024 characters, and error stacks are truncated to 4096 characters.

Pass the same redact object to the optional Next.js router adapters when you use custom query keys there.

Sensitive input interaction text for password, email, tel, and credit-card input types is replaced with [REDACTED].

Interaction telemetry uses the SDK's custom click/submit instrumentation by default. Add data-rum-ignore to an element or ancestor to suppress interaction spans for that subtree.

setUser(userId, attributes) does not automatically redact, hash, or mask values. Do not pass raw PII such as email addresses, phone numbers, names, or internal identifiers unless your telemetry policy allows it. Hash or sanitize user values before calling setUser.

Build And Test

npm run typecheck
npm run build
npm test

Releases

Releases are managed with Changesets. See RELEASING.md for the contributor and npm publishing flow.

The test suite uses Vitest, Happy DOM, and fast-check. Property tests use the design tag format:

// Feature: rum-web-sdk, Property 33: Redaction invariants

Current Scope

This is a functional OpenTelemetry-based SDK foundation. It relies on upstream OpenTelemetry for providers, OTLP protobuf serialization, batching, and core browser auto-instrumentation, with SDK-owned browser delivery and persistence. The next hardening steps are full OTLP round-trip properties, mock collector integration tests, and browser smoke tests.