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

@vantinelai/nextjs

v0.2.4

Published

Vantinel AI Observability SDK — Next.js App Router integration

Downloads

21

Readme

@vantinel/nextjs

Next.js App Router integration for Vantinel — real-time AI agent observability & guardrails.

This package provides first-class Next.js support on top of the @vantinel/node-sdk (server) and @vantinel/js-sdk (browser), with React context, hooks, and a singleton factory that survives hot-reload.

Installation

npm install @vantinel/nextjs

Quick Start

1. Add environment variables

# .env.local
VANTINEL_API_KEY=vantinel_abc123
VANTINEL_PROJECT_ID=my-company

# Exposed to the browser
NEXT_PUBLIC_VANTINEL_API_KEY=vantinel_abc123
NEXT_PUBLIC_VANTINEL_COLLECTOR_URL=https://collector.yourcompany.com

2. Wrap your root layout

// app/layout.tsx
import { VantinelProvider } from '@vantinel/nextjs';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        <VantinelProvider
          apiKey={process.env.NEXT_PUBLIC_VANTINEL_API_KEY!}
          collectorUrl={process.env.NEXT_PUBLIC_VANTINEL_COLLECTOR_URL}
        >
          {children}
        </VantinelProvider>
      </body>
    </html>
  );
}

3. Monitor tools in Client Components

'use client';
import { useVantinel } from '@vantinel/nextjs/client';

export default function AgentPage() {
  const { track, captureError } = useVantinel();

  async function runSearch(query: string) {
    const decision = await track('search_database', { query });
    if (decision.decision === 'block') return;

    try {
      return await fetch('/api/search', { body: JSON.stringify({ query }) });
    } catch (err) {
      await captureError('search_database', err as Error);
    }
  }
}

4. Monitor tools in Server Components & API Routes

// app/api/agent/route.ts
import { createServerMonitor } from '@vantinel/nextjs/server';

const monitor = createServerMonitor({
  apiKey: process.env.VANTINEL_API_KEY!,
  projectId: process.env.VANTINEL_PROJECT_ID!,
});

export async function POST(req: Request) {
  const wrappedSearch = monitor.monitor('search_database', searchDatabase);
  const results = await wrappedSearch({ query: 'hello' });
  return Response.json(results);
}

API

<VantinelProvider>

React context provider. Place in your root app/layout.tsx.

import { VantinelProvider } from '@vantinel/nextjs';

<VantinelProvider
  apiKey="your-key"
  collectorUrl="https://collector.yourcompany.com"  // optional
  agentId="my-next-app"                             // optional
  dryRun={process.env.NODE_ENV !== 'production'}    // optional
  shadowMode={false}                                // optional
>
  {children}
</VantinelProvider>

useVantinel() — Client Components

Access the Vantinel client from any Client Component:

import { useVantinel } from '@vantinel/nextjs/client';

const {
  track,             // (toolName, args) => Promise<VantinelDecision>
  captureError,      // (toolName, error, metadata?) => Promise<void>
  ping,              // () => Promise<{ ok: boolean; latencyMs: number }>
  startTrace,        // () => string (UUID)
  setGlobalMetadata, // (metadata) => void
  flush,             // () => Promise<void>
} = useVantinel();

createServerMonitor(config) — Server Components & API Routes

Returns a VantinelMonitor singleton that persists across hot-reloads:

import { createServerMonitor } from '@vantinel/nextjs/server';

const monitor = createServerMonitor({
  apiKey: process.env.VANTINEL_API_KEY!,
  projectId: process.env.VANTINEL_PROJECT_ID!,
  agentId: 'api-route-agent',
  dryRun: process.env.VANTINEL_DRY_RUN === 'true',
});

// All VantinelMonitor methods available:
// monitor.monitor(), monitor.wrapOpenAI(), monitor.wrapLangChain()
// monitor.captureError(), monitor.ping(), monitor.flush(), etc.

createClientVantinel(config) — without Provider

Module-level singleton for Client Components that don't use the Provider pattern:

import { createClientVantinel } from '@vantinel/nextjs/client';

const vantinel = createClientVantinel({
  apiKey: process.env.NEXT_PUBLIC_VANTINEL_API_KEY!,
});

Trace Correlation

Link browser events to server-side AI calls with a shared trace ID:

// Client Component
const { track, startTrace } = useVantinel();
const traceId = startTrace();

// Pass trace ID to your API route
await fetch('/api/agent', {
  headers: { 'X-Vantinel-Trace': traceId },
  body: JSON.stringify({ query }),
});
// API Route
const monitor = createServerMonitor({ ... });

export async function POST(req: Request) {
  const traceId = req.headers.get('X-Vantinel-Trace') ?? undefined;
  const wrappedFn = monitor.monitor('openai_call', callOpenAI, { traceId });
  return Response.json(await wrappedFn());
}

Environment Variables

Server-side (API routes, Server Components)

| Variable | Required | Description | |---|---|---| | VANTINEL_API_KEY | Yes | API key | | VANTINEL_PROJECT_ID | Yes | Organization ID | | VANTINEL_COLLECTOR_URL | No | Defaults to http://localhost:8000 | | VANTINEL_DRY_RUN | No | Set true to disable HTTP in CI | | VANTINEL_SHADOW_MODE | No | Set true for shadow mode |

Browser-side (Client Components)

| Variable | Required | Description | |---|---|---| | NEXT_PUBLIC_VANTINEL_API_KEY | Yes | API key (exposed to browser) | | NEXT_PUBLIC_VANTINEL_COLLECTOR_URL | No | Collector URL (must be HTTPS for non-localhost) |

License

MIT © Vantinel AI