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

@kya-os/checkpoint-nextjs

v1.10.0

Published

Checkpoint Next.js middleware for AI agent detection (formerly @kya-os/agentshield-nextjs)

Readme

@kya-os/checkpoint-nextjs

Next.js middleware for Checkpoint AI agent detection and enforcement.

Features

  • 🚀 Next.js Middleware: Edge-compatible middleware for all routes
  • 🧩 Two Deployment Shapes: In-process WASM engine or SaaS gateway
  • 🎯 Flexible Actions: Block, redirect, or challenge detected agents
  • 🛡️ Edge Runtime: Optimized for Vercel Edge Functions
  • 📊 Dashboard Reporting: Detections land in your Checkpoint dashboard

Two deployment shapes

This package ships two complementary middleware factories. Pick the one that fits your runtime; both are first-class and supported.

| Shape | Factory | Where verification runs | Use when | | ---------------- | ------------------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Local engine | withCheckpoint | In-process, via WASM (kya-os-engine) | You want the lowest possible latency, deterministic verdicts, no network round-trip per request, and your runtime can load the WASM artifact (Vercel Node, Vercel Edge with the bundled artifact, Cloudflare Workers with nodejs_compat). This is the canonical Phase D output. | | SaaS gateway | withCheckpointApi | Cloudflare DNS gateway (https://detect.checkpoint-gateway.ai) | You want centralized policy + dashboard rules without a redeploy, you're on a runtime where the WASM artifact won't load (bare-Edge, browser embedding), or you want a single HTTPS hop with cached verdicts. Trades ~30–50ms of edge latency for zero local engine state. |

Both factories return a Next.js middleware function — the request/response contract is identical. You can run both side-by-side in the same app on different routes if your policy demands it.

// middleware.ts — local engine
import { withCheckpoint } from '@kya-os/checkpoint-nextjs';
export default withCheckpoint({ tenantHost: 'demo.example' });

// middleware.ts — SaaS gateway
import { withCheckpointApi } from '@kya-os/checkpoint-nextjs';
export default withCheckpointApi({
  apiKey: process.env.CHECKPOINT_API_KEY!,
  onBlock: 'redirect',
  redirectUrl: '/blocked',
});

Pre-Phase-D the SaaS-gateway factory shipped as withAgentShield; the name is preserved as a @deprecated alias for one release. Same for AgentShieldClient / AgentShieldClientConfig → CheckpointApiClient / CheckpointApiClientConfig. New code should import the Checkpoint* names.

Installation

npm install @kya-os/checkpoint-nextjs

Quick Start

Client-IP trust policy

Client-IP resolution defaults to the direct framework or socket peer. For a Next.js deployment behind Vercel, select the Vercel profile explicitly:

withCheckpoint({
  tenantHost: 'your.tenant.example',
  clientIpPolicy: { platform: 'vercel' },
});

Forwarding headers are normalized and are not trusted by the middleware without a matching deployment profile. See the client-IP resolution runbook for the profile matrix and proxy-chain guidance.

Middleware Setup

Create middleware.js (or middleware.ts) in your project root:

import { withCheckpointApi } from '@kya-os/checkpoint-nextjs';

export default withCheckpointApi({
  apiKey: process.env.CHECKPOINT_API_KEY,
});

export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};

Enforcement happens in the middleware, before your pages and route handlers run: blocked or challenged requests never reach your code. Tune what gets blocked in your Checkpoint dashboard policy.

Client-Side Detection

This package is server-side middleware; it does not ship client-side React hooks. (The legacy useAgentDetection hook was removed along with the AgentDetector class it wrapped.) For client-side detection, such as conditionally rendering content or tracking agent visits from the browser, use the JavaScript Beacon or the Marketing Pixel alongside the middleware.

Middleware Configuration

The SaaS-gateway shape (withCheckpointApi) accepts:

import { withCheckpointApi } from '@kya-os/checkpoint-nextjs';

export default withCheckpointApi({
  // API key (or set the CHECKPOINT_API_KEY env var)
  apiKey: process.env.CHECKPOINT_API_KEY,

  // Action when an agent should be blocked: 'block' | 'redirect' | 'challenge'
  // Default: uses the policy from your dashboard
  onBlock: 'block',

  // Target when onBlock is 'redirect'
  redirectUrl: '/blocked',

  // Skip enforcement for paths (glob patterns)
  skipPaths: ['/api/webhooks', '/health'],

  // Custom blocked response
  blockedResponse: {
    status: 403,
    message: 'Access denied',
  },

  // Edge detection: lower latency, catches non-JS clients. Default: true
  useEdge: true,

  // Request timeout in ms. Default: 5000
  timeout: 5000,

  // Fail open (allow) on API errors. Default: true
  failOpen: true,

  // Observability callback when an agent is detected
  onAgentDetected: async (request, decision) => {
    console.log('Agent detected:', decision.reason);
  },

  // Enable debug logging
  debug: false,
});

The local-engine shape (withCheckpoint) takes a CheckpointConfig instead: tenantHost (required), plus optional enforcementMode ('enforce' | 'observe'), apiKey (enables dashboard reporting), projectId (enforces your deployed dashboard policy in-process), and more. See the middleware docs for the full option tables for both shapes.

Actions

Block Agents

export default withCheckpointApi({
  apiKey: process.env.CHECKPOINT_API_KEY,
  onBlock: 'block',
  blockedResponse: {
    status: 403,
    message: 'Automated access not allowed',
    headers: {
      'Content-Type': 'application/json',
      'X-Robots-Tag': 'noindex',
    },
  },
});

Redirect Agents

export default withCheckpointApi({
  apiKey: process.env.CHECKPOINT_API_KEY,
  onBlock: 'redirect',
  redirectUrl: '/blocked',
});

By default a redirect verdict is delivered as an HTTP 401 "instruct" envelope with a link header pointing the agent at the redirect URL, which LLM fetchers surface as a clickable link. Set redirectMode: 'http' for a legacy 302 response (only useful when your traffic is real browsers).

Custom Logic

customBlockedResponse runs when the verdict is a block; whatever it returns becomes the response:

import { NextResponse } from 'next/server';

export default withCheckpointApi({
  apiKey: process.env.CHECKPOINT_API_KEY,
  customBlockedResponse: async (request, decision) => {
    if (decision.confidence > 0.9) {
      // High confidence: hard block
      return NextResponse.json({ error: 'Blocked' }, { status: 403 });
    }
    // Lower confidence: send to a verification page instead
    return NextResponse.redirect(new URL('/verify', request.url));
  },
});

API Routes Integration

API routes matched by the matcher are protected by the middleware itself: a request that your policy blocks is answered with the verdict (403, redirect, or challenge) before your route handlers execute. Handlers need no detection code of their own:

// app/api/protected/route.js
import { NextResponse } from 'next/server';

export async function GET() {
  // Only requests your policy allows ever reach this point.
  return NextResponse.json({ data: 'Protected content' });
}

Advanced Usage

Path-Specific Configuration

Use includePaths and skipPaths (glob patterns) to scope enforcement without touching the matcher:

import { withCheckpointApi } from '@kya-os/checkpoint-nextjs';

export default withCheckpointApi({
  apiKey: process.env.CHECKPOINT_API_KEY,

  // Only enforce on these paths (overrides dashboard policy)
  includePaths: ['/api/*', '/admin/*'],

  // Never enforce on webhooks or health checks
  skipPaths: ['/api/webhooks', '/health'],
});

TypeScript Support

Full TypeScript support with proper types:

import type { NextRequest } from 'next/server';
import {
  withCheckpointApi,
  type CheckpointApiMiddlewareConfig,
  type EnforcementDecision,
} from '@kya-os/checkpoint-nextjs';

const config: CheckpointApiMiddlewareConfig = {
  onBlock: 'block',
  onAgentDetected: async (request: NextRequest, decision: EnforcementDecision) => {
    // Fully typed parameters
    console.log(decision.confidence);
  },
};

export default withCheckpointApi(config);

Examples

E-commerce Protection

// Protect product pages from scrapers
import { withCheckpointApi } from '@kya-os/checkpoint-nextjs';

export default withCheckpointApi({
  apiKey: process.env.CHECKPOINT_API_KEY,
  onBlock: 'redirect',
  redirectUrl: '/captcha',
  skipPaths: ['/api/webhooks', '/health'],
});

export const config = {
  matcher: ['/products/:path*', '/search/:path*'],
};

Content Publishing

// Allow search engines through, block other agents
import { NextResponse } from 'next/server';
import { withCheckpointApi } from '@kya-os/checkpoint-nextjs';

export default withCheckpointApi({
  apiKey: process.env.CHECKPOINT_API_KEY,
  customBlockedResponse: async (request, decision) => {
    const userAgent = request.headers.get('user-agent') || '';

    // Let known search engines continue even when the policy blocks
    if (/googlebot|bingbot|slurp/i.test(userAgent)) {
      return NextResponse.next();
    }

    return NextResponse.json(
      { error: 'Bot access restricted', reason: decision.reason },
      { status: 403 }
    );
  },
});

License

MIT OR Apache-2.0

Browser integrity

For opt-in classification, signed posture and scoped consent step-up, see the browser integrity rollout runbook.