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

@vibemonitor/nextjs

v0.1.0

Published

Vibemonitor Next.js SDK — single install, routes to browser/node/edge impls via conditional exports.

Readme

@vibemonitor/nextjs

One-install Vibemonitor SDK for Next.js. Automatically routes to the right runtime-specific implementation (browser / Node / edge) via conditional exports.

Why a meta-package?

Next.js runs your code in three separate JavaScript runtimes, and each needs its own vibemonitor.init() call:

| Runtime | Where your code runs | |---|---| | Browser | Client components, hooks, event handlers | | Node.js | Server components (SSR), API routes (app/api/**) | | Edge | middleware.ts, routes with export const runtime = 'edge' |

@vibemonitor/nextjs is a thin wrapper that uses package.json conditional exports so you import the same package name in all three places. The bundler picks the right implementation automatically.


Installation

npm install @vibemonitor/nextjs

This transitively installs @vibemonitor/browser + @vibemonitor/node + @vibemonitor/core. You never install those directly.


Environment variables

Add to .env.local:

# Browser — baked into the client JS bundle at build time.
# NEXT_PUBLIC_ prefix makes it readable in client components.
NEXT_PUBLIC_VIBEMONITOR_API_KEY=vmsdk_browser_token_here

# Server — stays on the server, never shipped to browser.
VIBEMONITOR_API_KEY=vmsdk_server_token_here

# Optional — toggle SDK on/off without code changes
VIBEMONITOR_ENABLED=true

# Optional — emit [vibemonitor] diagnostic stderr lines during debugging
VIBEMONITOR_DEBUG=false

Get your tokens from the Vibemonitor dashboard → Settings → API Keys.


Setup — three files

File 1 · src/instrumentation-client.ts (browser runtime)

Next.js auto-loads this file in the browser bundle. Create it at exactly this path.

import vibemonitor from "@vibemonitor/nextjs";

vibemonitor.init({
  apiKey: process.env.NEXT_PUBLIC_VIBEMONITOR_API_KEY!,
  service: "my-frontend",
  environment: process.env.NODE_ENV,
});

File 2 · src/instrumentation.ts (router for server runtimes)

Next.js auto-loads this file at server startup. It dispatches to the right config based on process.env.NEXT_RUNTIME.

export async function register() {
  if (process.env.NEXT_RUNTIME === "nodejs") {
    await import("../vibemonitor.server.config");
  }
  if (process.env.NEXT_RUNTIME === "edge") {
    await import("../vibemonitor.edge.config");
  }
}

File 3 · vibemonitor.server.config.ts (Node.js runtime)

Put this at the repo root (or wherever instrumentation.ts imports from).

import vibemonitor from "@vibemonitor/nextjs";

vibemonitor.init({
  apiKey: process.env.VIBEMONITOR_API_KEY!,
  service: "my-app-server",
  environment: process.env.NODE_ENV,
});

File 4 · vibemonitor.edge.config.ts (Edge runtime — only if you use middleware)

Skip this file if your app has no middleware.ts and no runtime: 'edge' routes.

import vibemonitor from "@vibemonitor/nextjs";

vibemonitor.init({
  apiKey: process.env.VIBEMONITOR_API_KEY!,
  service: "my-app-edge",
});

What gets captured per runtime

| Runtime | Captured automatically | |---|---| | Browser | console.log/info/warn/error/debug, window.onerror, unhandled promise rejections, explicit vibemonitor.log() | | Node.js | console.*, process.on('uncaughtException' / 'unhandledRejection'), explicit calls, SIGTERM/SIGINT graceful flush | | Edge | console.*, explicit calls (no window, no process hooks available) |

You can also manually log structured events from anywhere:

import vibemonitor from "@vibemonitor/nextjs";

vibemonitor.log("INFO", "Checkout completed", {
  userId: "u_123",
  amount: 49.99,
});

Configuration reference

Full list of options (all optional except apiKey):

vibemonitor.init({
  // Required
  apiKey: "vmsdk_xxx",

  // Identification
  service: "my-app",                    // defaults to hostname / auto-detected
  environment: "production",             // env var: VIBEMONITOR_ENV
  version: "2.3.1",                      // env var: VIBEMONITOR_VERSION

  // Endpoint — rarely overridden
  endpoint: "https://api.vibemonitor.ai/api/v1/ingest/logs",

  // Master switches
  enabled: true,                         // env: VIBEMONITOR_ENABLED, NEXT_PUBLIC_VIBEMONITOR_ENABLED
  debug: false,                          // env: VIBEMONITOR_DEBUG, NEXT_PUBLIC_VIBEMONITOR_DEBUG

  // Transport tuning
  flushIntervalMs: 2000,
  maxQueueSize: 1000,
  batchSize: 50,

  // Capture layers (turn off if unwanted)
  captureConsole: true,
  captureGlobalErrors: true,

  // PII scrubbing
  scrubPatterns: ["email", "jwt", "oauth_code", ...],  // defaults to full list
  customScrubPatterns: { myId: /CUST-\d+/g },

  // Hook to mutate or drop entries before network send
  beforeSend: (entry) => entry,         // return null to drop
});

Precedence for every option

init({ option: value })    ← kwarg wins
    ↓ else
VIBEMONITOR_<NAME> env var (server runtime)
    ↓ else
NEXT_PUBLIC_VIBEMONITOR_<NAME> env var (browser runtime, bundled at build time)
    ↓ else
Hardcoded SDK default

How routing works under the hood

package.json conditional exports:

  "browser"    → dist/browser.js  (wraps @vibemonitor/browser)
  "edge-light" → dist/browser.js  (edge APIs ≈ browser subset)
  "workerd"    → dist/browser.js  (Cloudflare Workers)
  "node"       → dist/node.js     (wraps @vibemonitor/node)
  "default"    → dist/browser.js  (fallback)

Next.js's bundler picks the right condition per runtime. Vite, webpack, esbuild all honor these. You never touch this mechanism.


FAQ

Q: Do I need middleware to use Vibemonitor? No. middleware.ts is only needed for edge-runtime code. If you don't have it, skip File 4.

Q: Can I disable capture in dev? Yes. Set VIBEMONITOR_ENABLED=false in .env.local. The SDK becomes a complete no-op (no network, no listeners).

Q: Are my server tokens exposed in the browser bundle? Only env vars prefixed NEXT_PUBLIC_ get baked into the browser bundle. Use VIBEMONITOR_API_KEY (no prefix) for server-only tokens.

Q: Can I use a different token for server vs browser? Yes — recommended. Mint two tokens in your Vibemonitor dashboard, set them as NEXT_PUBLIC_VIBEMONITOR_API_KEY and VIBEMONITOR_API_KEY. Revoking one doesn't affect the other.

Q: What if the workflow says "404 Not Found" when hitting the endpoint? Your endpoint URL is wrong. Default is https://api.vibemonitor.ai/api/v1/ingest/logs. If you're running vm-api locally, override with endpoint: "http://localhost:8000/api/v1/ingest/logs".


License

Proprietary. See LICENSE.