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

@interfere/next

v11.0.5

Published

Build software that never breaks.

Readme


Getting Started

Prerequisites

  • Next.js >=16
  • React >=19
  • Node.js >=20

Installation

npm install @interfere/next

Quick Start

1. Wrap your Next.js config

// next.config.ts
import { withInterfere } from "@interfere/next/config";
import type { NextConfig } from "next";

const config: NextConfig = {};

export default withInterfere(config);

2. Wire instrumentation

// instrumentation.ts
export { onRequestError, register } from "@interfere/next/instrumentation";

3. Add the provider

// app/layout.tsx
import { InterfereProvider } from "@interfere/next/provider";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <InterfereProvider>{children}</InterfereProvider>
      </body>
    </html>
  );
}

Environment Variables

| Variable | Required | Description | | --- | --- | --- | | INTERFERE_PUBLIC_KEY | Yes | Surface public key in the interfere_public_us_* or interfere_public_eu_* format. Public by design; used for ingestion. | | INTERFERE_API_KEY | Yes for release metadata | Interfere secret key in the interfere_secret_us_* or interfere_secret_eu_* format. Server-side build credential; never expose in browser code. | | INTERFERE_API_URL | No | Override the ingest endpoint in direct mode (e.g. a regional endpoint). Defaults to Interfere's endpoint. |

Migrating From 0.x

Upgrade all @interfere/* SDK packages together. Keep the env var names, but replace old int_pub_* / interfere_pk_* values with the dashboard's regional public key, and replace old ak_* / interfere_ak_* build keys with the regional Interfere secret key.

Ingest Endpoint

By default the SDK posts telemetry to Interfere's endpoint. Ingest requests never carry cookies. Set apiHost to a subdomain of your own site that resolves to Interfere via a DNS record — this survives ad-blockers with no server-side component:

// next.config.ts
export default withInterfere({
  interfere: { apiHost: "https://in.yourapp.com" },
});

Add a CNAME record pointing your subdomain at the target shown in your dashboard; Interfere provisions the TLS certificate automatically. To target a regional endpoint instead, set apiHost (or the INTERFERE_API_URL env) to it.

Identity Management

Link sessions to your authenticated users with identity.set():

import { useInterfere } from "@interfere/next/provider";

function useInterfereIdentity() {
  const { identity } = useInterfere();

  // Clerk, Auth0, etc.
  const { user } = useAuthProvider();

  useEffect(() => {
    if (user) {
      identity.set({
        identifier: user.id,
        name: user.name,
        email: user.email,
        source: { type: "clerk", name: "Clerk" },
      });
    } else {
      identity.clear();
    }
  }, [user]);

  return null;
}

Parameters

| Field | Required | Description | | --- | --- | --- | | identifier | Yes | Unique user ID (your internal ID, not email) | | source | Yes | Auth source: { type: "clerk", name: "Clerk" }, { type: "auth0", name: "Auth0" }, or { type: "custom", name: "Your Provider" } | | name | No | Display name | | email | No | Email address | | avatar | No | Avatar URL | | traits | No | Arbitrary key-value metadata (Record<string, unknown>) |

API

| Method | Description | | --- | --- | | identity.set(params) | Link the current session to a user. Deduplicated per session — only the first call sends a request. | | identity.clear() | Clears the linked identity and rotates the session. Call on logout. | | identity.get() | Returns the current IdentifyParams, or null if no identity has been set. |

Identity is automatically cleared when the SDK is closed. Call identity.clear() on logout to start a fresh anonymous session.

Consent Management

By default, all SDK features are active. To gate features behind user consent, pass a consent prop to the provider:

// app/layout.tsx
import { InterfereProvider } from "@interfere/next/provider";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <InterfereProvider consent={{ analytics: true, replay: false }}>
          {children}
        </InterfereProvider>
      </body>
    </html>
  );
}

Consent categories

| Category | Plugins | Gated? | | --- | --- | --- | | necessary | Error tracking | Always on | | analytics | Page events, rage clicks, fingerprint | Yes | | replay | Session replay | Yes |

Omitting the consent prop disables gating entirely (all features load). Passing it enables gating — only necessary plugins plus explicitly consented categories will activate.

Imperative API

Use consent.set() and consent.get() from the useInterfere hook:

const { consent } = useInterfere();

consent.set({ analytics: true, replay: true }); // selective
consent.set();                                   // grant all
consent.get();                                   // current state, or null if no gating

Integration with consent libraries

Works with any consent management platform — c15t, CookieYes, OneTrust, etc.:

import { InterfereProvider } from "@interfere/next/provider";

function Layout({ children }: { children: React.ReactNode }) {
  const { has } = useConsentManager(); // from your CMP

  return (
    <InterfereProvider
      consent={{ analytics: has("measurement"), replay: has("experience") }}
    >
      {children}
    </InterfereProvider>
  );
}

Initial consent via bootstrap

To set consent before React renders (avoiding any window where non-consented plugins might load), pass it to init():

// instrumentation-client.ts
import { init } from "@interfere/next/instrument-client";

init({ consent: { analytics: false, replay: false } });

The provider's consent prop will then keep it in sync as the user updates their preferences.

What's Included

  • Error tracking — automatic capture of server and client errors with rich stack traces
  • Session replay — full visual playback of user sessions
  • Source maps — automatic upload during production builds
  • Release tracking — links builds to Git commits and deployments
  • Server capturecaptureError() for manual server-side error reporting

License

MIT