Official TopStats Analytics middleware for the four big Node server frameworks,
each as its own package on the @topstats/analytics SDK:
| Package | Framework | Install |
|---|---|---|
@topstats/express |
Express | npm i @topstats/express |
@topstats/fastify |
Fastify | npm i @topstats/fastify |
@topstats/hono |
Hono (Node, Bun, Deno, Workers) | npm i @topstats/hono |
@topstats/nestjs |
NestJS (both adapters) | npm i @topstats/nestjs |
Every middleware does the same thing:
- Captures an
http_requestevent per request: route template (never the raw URL, so ids don't explode property cardinality), method, status and duration. - Captures
http_erroron failures. - Optional actor extraction (
actorcallback), ignore paths, sampling. - Capture happens after the response has left and never throws into your request path. Your API key never appears in logs or errors.
import express from 'express'
import { topstats } from '@topstats/express'
const app = express()
const analytics = topstats({ apiKey: process.env.TOPSTATS_API_KEY })
app.use(analytics)
// custom events any time:
analytics.client.capture('checkout_completed', { total: 42 })import Fastify from 'fastify'
import { topstatsPlugin } from '@topstats/fastify'
const app = Fastify()
await app.register(topstatsPlugin({ apiKey: process.env.TOPSTATS_API_KEY }))The plugin registers at the root and sees every route; closing the app flushes the buffer.
import { Hono } from 'hono'
import { topstats } from '@topstats/hono'
const app = new Hono()
app.use(topstats({ apiKey: env.TOPSTATS_API_KEY }))On Cloudflare Workers there is no background timer, so the middleware flushes
through ctx.waitUntil automatically (flushStrategy: 'auto'). On Node and
Bun the SDK's batching loop does its usual job.
import { TopStatsModule, TopStatsService } from '@topstats/nestjs'
@Module({
imports: [TopStatsModule.forRoot({ apiKey: process.env.TOPSTATS_API_KEY })],
})
export class AppModule {}A global interceptor tracks every HTTP request on either adapter, and
TopStatsService is injectable anywhere for custom events.
| Option | Meaning |
|---|---|
apiKey / client |
Create a client, or reuse one you already have |
host |
Override the API host |
source |
_source on events; defaults to the framework name |
actor |
Callback resolving { actor, actorLabel } from the request |
ignorePaths |
Exact strings or RegExps that produce no events |
sampleRate |
Fraction of requests captured, 0..1 |