Supported frameworks
Version 0.1. Express and Fastify (tested on 5), NestJS, Next.js App Router route handlers,fetch and the http/https modules.Install
Terminal
npm install @codeskop/nodeTerminal
pnpm add @codeskop/nodeTerminal
yarn add @codeskop/nodeInitialize
Call init once, before your app starts handling requests. On its own this reports uncaught exceptions and unhandled rejections (Node still exits exactly as it would without Codeskop) and records outgoing fetch and http calls.
instrument.ts
import * as codeskop from "@codeskop/node"; codeskop.init({ apiKey: process.env.CODESKOP_API_KEY, // cs_live_pk_… (public key) environment: "production", // optional release: "1.4.2", // optional: auto-detected on most hosts});Add your framework
server.ts
import express from "express";import * as codeskop from "@codeskop/node"; codeskop.init({ apiKey: process.env.CODESKOP_API_KEY }); const app = express();app.use(codeskop.expressMiddleware()); // first app.get("/orders/:id", getOrder); app.use(codeskop.expressErrorHandler()); // after your routes, before your own error handlersserver.ts
import Fastify from "fastify";import * as codeskop from "@codeskop/node"; codeskop.init({ apiKey: process.env.CODESKOP_API_KEY }); const app = Fastify();await app.register(codeskop.fastifyPlugin);main.ts
// main.ts: NestJS runs on Express (default) or Fastify; add the matching integration.const app = await NestFactory.create(AppModule);app.use(codeskop.expressMiddleware());app.useGlobalFilters(/* your filters */);route.ts
// app/api/orders/[id]/route.tsimport * as codeskop from "@codeskop/node"; export const GET = codeskop.withCodeskop( async (req: Request) => Response.json(await getOrder(req)), { route: "/api/orders/[id]" },);Requests are recorded by route (/orders/{id}), and errors carry the route they happened on. Health checks aren't recorded; change that with ignoreRoutes.
Report errors yourself
try { await charge(order);} catch (err) { codeskop.captureException(err, { tags: { provider: "stripe" } });} codeskop.captureMessage("Inventory sync skipped");codeskop.setUser(req.user.id); // inside a request: your own ID, never an emailOptions
| Option | Type | Default | Description |
|---|---|---|---|
| apiKey | string | CODESKOP_API_KEY | The project's public key. Secret keys are refused and the SDK stays off. |
| environment | string | production | Shown on events. Env var CODESKOP_ENVIRONMENT. |
| release | string | auto | Auto-detected on Render, Heroku, Vercel, Railway, Cloud Run and GitHub Actions. Env var CODESKOP_RELEASE. |
| captureRequests | boolean | true | Record incoming requests. |
| captureOutgoing | boolean | true | Record fetch and http calls. |
| ignoreRoutes | string[] | health checks | Glob patterns never recorded. |
| ignoreExceptions | string[] | [] | Error class names never sent. |
| beforeSend | function | none | Edit or drop any event before it's sent. |
| debug | boolean | false | Log what the SDK does. |
Clusters and serverless
PM2 and cluster workers each send their own events. On AWS Lambda or other functions, flush at the end of each invocation:
export const handler = async (event) => { try { return await process(event); } finally { await codeskop.flush(2000); // send before the runtime freezes }};Privacy
Never captured: request or response bodies, cookies, Authorization headers and query strings. See Privacy & Security.