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

@trapify-tech/browser

v0.1.2

Published

Trapify error tracking SDK for browser and Node.js

Readme

@trapify-tech/browser

Error tracking SDK for browser and Node.js. Captures unhandled exceptions and sends them to Trapify with full stack traces, breadcrumbs, and user context.


Table of contents


Install

npm install @trapify-tech/browser

Or via CDN (no build step):

<script src="https://cdn.jsdelivr.net/npm/@trapify-tech/browser/dist/trapify.min.js"></script>
<script>
  Trapify.init({ dsn: 'your-32-char-dsn-key' });
</script>

Browser SDK

Import from the package root.

Quick start

import { init } from '@trapify-tech/browser';

init({ dsn: 'your-32-char-dsn-key' });

Call init once at application startup (e.g. main.ts). Unhandled errors and promise rejections are captured automatically.

Configuration

| Option | Type | Default | Description | |--------|------|---------|-------------| | dsn | string | required | 32-character hex key from your Trapify project settings | | environment | string | null | Attached to every event ('production', 'staging', etc.) | | release | string | null | App version string | | maxBreadcrumbs | number | 50 | Max breadcrumbs retained in memory | | autoCapture | boolean | true | Capture window.onerror and unhandledrejection | | captureConsole | boolean | true | Capture console.error/warn/info/log as breadcrumbs | | captureFetch | boolean | true | Capture fetch requests as breadcrumbs | | debug | boolean | false | Log SDK errors to console | | beforeSend | function | — | Hook called before every send — return null to drop | | endpoint | string | Trapify production | Override the ingest URL (useful for testing) |

init({
  dsn: 'your-32-char-dsn-key',
  environment: 'production',
  release: '1.0.0',
  beforeSend: (event) => {
    if (event.environment === 'development') return null; // drop dev errors
    return event;
  },
});

Manual capture

import { captureException, captureMessage } from '@trapify-tech/browser';

try {
  riskyOperation();
} catch (err) {
  captureException(err as Error);
}

captureMessage('Checkout flow started', 'info');

User context

import { setUser } from '@trapify-tech/browser';

setUser({ id: 'u_123', email: '[email protected]', username: 'alice' });

// On logout
setUser(null);

Tags

import { setTag } from '@trapify-tech/browser';

setTag('plan', 'pro');
setTag('region', 'eu-west');

Tags are attached to every subsequent event.

Breadcrumbs

import { addBreadcrumb } from '@trapify-tech/browser';

addBreadcrumb({
  timestamp: new Date().toISOString(),
  type: 'ui',
  category: 'click',
  message: 'Checkout button clicked',
});

Console calls, fetch requests, and navigation events are captured automatically when captureConsole, captureFetch, and navigation patching are enabled.

beforeSend hook

init({
  dsn: '...',
  beforeSend: (event) => {
    // Scrub sensitive data
    if (event.user) {
      event = { ...event, user: { ...event.user, email: '[redacted]' } };
    }
    // Drop noisy errors
    if (event.exception?.value?.includes('ResizeObserver')) return null;
    return event;
  },
});

Shutdown

import { close } from '@trapify-tech/browser';

close(); // removes all global handlers — useful in tests or SSR teardown

Direct client usage

For multiple isolated clients (e.g. different DSNs in a monorepo):

import { TrapifyClient } from '@trapify-tech/browser';

const client = new TrapifyClient({ dsn: 'your-dsn', autoCapture: false });
client.captureException(new Error('Something went wrong'));
client.close();

Framework examples

React / Vite

// src/main.tsx
import { init } from '@trapify-tech/browser';

init({
  dsn: import.meta.env.VITE_TRAPIFY_DSN,
  environment: import.meta.env.MODE,
  release: import.meta.env.VITE_APP_VERSION,
});

Next.js (App Router)

// instrumentation.ts
export async function register() {
  if (typeof window !== 'undefined') {
    const { init } = await import('@trapify-tech/browser');
    init({ dsn: process.env.NEXT_PUBLIC_TRAPIFY_DSN! });
  }
}

Node.js SDK

Import from the /node subpath. This entry point uses the native https module (no fetch dependency) and adds server-specific helpers: withTrapify, errorHandler, and flush.

import { init, captureException } from '@trapify-tech/browser/node';

Quick start (Node)

import { init } from '@trapify-tech/browser/node';

init({
  dsn: process.env.TRAPIFY_DSN!,
  environment: 'production',
  autoCapture: true, // hooks process.uncaughtException + unhandledRejection
});

Configuration (Node)

All browser options are supported, plus:

| Option | Type | Default | Description | |--------|------|---------|-------------| | captureConsole | boolean | false | Capture console calls as breadcrumbs (default off — high noise in server logs) |

Firebase Cloud Functions

Use withTrapify to wrap any async Cloud Function handler. It captures unexpected errors (those that would surface as internal to the client) and re-throws them. Intentional HttpsError throws are passed through without capture.

// functions/src/billing/createCheckoutSession.ts
import { onCall, HttpsError } from 'firebase-functions/v2/https';
import { defineSecret } from 'firebase-functions/params';
import { init, withTrapify } from '@trapify-tech/browser/node';

const TRAPIFY_DSN = defineSecret('TRAPIFY_DSN');

export const createCheckoutSession = onCall(
  { secrets: [TRAPIFY_DSN] },
  withTrapify(async (request) => {
    // init inside the handler — secrets are only available at invocation time
    init({ dsn: TRAPIFY_DSN.value(), environment: 'production', autoCapture: false });

    if (!request.auth) throw new HttpsError('unauthenticated', 'Sign in required');
    // ... business logic
  }),
);

withTrapify works with any async function, not just Cloud Functions:

import { withTrapify } from '@trapify-tech/browser/node';

const handler = withTrapify(async (event: SQSEvent) => {
  // process event
});

Express error middleware

Add errorHandler() as the last middleware in your Express app. It captures the error and calls next(err) to continue the chain.

import express from 'express';
import { init, errorHandler } from '@trapify-tech/browser/node';

init({ dsn: process.env.TRAPIFY_DSN!, environment: 'production' });

const app = express();

app.use('/api', router);

// Must be last — after all routes
app.use(errorHandler());

Flushing before process exit

In serverless environments the process may be frozen before in-flight HTTP requests complete. Call flush() after sending events and before returning from the handler.

import { captureException, flush } from '@trapify-tech/browser/node';

try {
  await riskyOperation();
} catch (err) {
  captureException(err as Error);
  await flush(2000); // wait up to 2s for the event to be sent
  throw err;
}

withTrapify calls flush automatically before re-throwing, so you don't need to do this manually when using the wrapper.


Publishing

From the repo root:

# Bump version (patch / minor / major)
npm run sdk:release patch

# Publish to npm
npm run sdk:publish

sdk:publish runs typecheck → tests → build via prepublishOnly before the package is uploaded. A broken SDK cannot be published.