Skip to content

eleven-labs/nest-profiler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

94 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

nest-profiler

Powered & maintained by Eleven Labs

Powered & maintained by Eleven Labs

CI Quality Coverage License: MIT

Documentation Node >= 22 Built with NestJS TypeScript strict Code style: Prettier

Conventional Commits Dependabot enabled PRs welcome

A Symfony Web Profiler-inspired toolkit for NestJS applications. Each profiled execution receives a unique token, and a rich panel UI at /_profiler lets you inspect request data, logs, exceptions, performance spans, and much more — in real time.

The ecosystem is built around an extensible collector architecture: the core package provides the profiler engine, storage, and UI, while optional sub-packages each add a dedicated panel as a self-contained NestJS module.

Profiler UI — profiles list with filters, HTTP statuses, durations and the global Config panel

Packages

Each package is a self-contained NestJS module with its own README:

Full guides and API reference live on the documentation site (pnpm docs:dev, then http://localhost:3002).

Panels at a glance

Database panel HTTP Client panel Cache panel
Database (TypeORM) HTTP Client (Axios) Cache
Security panel Validator panel Timeline panel
Security (JWT/Auth) Validator (class-validator) Timeline (spans)

Quickstart

Requirements: Node.js 22+, pnpm 10+

pnpm install        # install dependencies
pnpm build          # build all packages
pnpm test:cov       # run the test suite with coverage
pnpm docs:dev       # serve the documentation site at http://localhost:3002

To try the profiler against a real app, start the databases and the demo API, then open http://localhost:3000/_profiler:

pnpm docker:up      # Postgres + MongoDB (runs in the background)
pnpm example:dev

Installation

Packages are published to the public npm registry — install them like any other dependency, no authentication required:

pnpm add @eleven-labs/nest-profiler nestjs-cls
import { ProfilerModule } from '@eleven-labs/nest-profiler';

@Module({
  imports: [
    ProfilerModule.forRoot({
      isGlobal: true,
      enabled: process.env.NODE_ENV !== 'production',
    }),
  ],
})
export class AppModule {}

Add optional collectors in their respective feature modules:

pnpm add @eleven-labs/nest-profiler-typeorm
import { TypeOrmCollectorModule } from '@eleven-labs/nest-profiler-typeorm';

@Module({
  imports: [TypeOrmCollectorModule.forRoot({ slowQueryThreshold: 50 })],
})
export class ProductsModule {}

Repository Layout

A pnpm + Turbo monorepo. Publishable packages live under packages/; everything else supports them.

packages/
  nest-profiler/            core profiler engine, storage, and UI
  nest-profiler-*/          optional collectors (typeorm, mikro-orm, axios, cache, auth, config, mongoose, validator, graphql, commander)
  configs/                  shared @repo/* tooling presets (eslint, jest, prettier, typescript)
examples/
  api/                      NestJS demo app with all collectors enabled
docs/                       Fumadocs documentation site
scripts/                    repository automation and release helpers

Architecture

The profiler is a thin pipeline wired into the standard NestJS request lifecycle, designed so that collectors stay decoupled from the core and disabling the profiler costs almost nothing.

Two layers: active and inert

ProfilerModule.forRoot() resolves enabled synchronously and registers one of two layers:

  • Active (default) — mounts the middleware, the global interceptor, the /_profiler controller, the collector registry and storage.
  • Inert (enabled: false) — registers only ProfilerService, as a no-op. It stays injectable everywhere, so application code that calls profiler.startSpan(...) or profiler.createLogger(...) keeps working with zero overhead and no conditional wiring on your side. Turn the profiler on in development and off in production with a single flag.

Request lifecycle (HTTP)

request
   │
   ▼
ProfilerMiddleware ── creates a Profile (unique token), stores it in the
   │                   request-scoped CLS context (nestjs-cls)
   ▼
route handler ──────── your code; collectors append entries into the active
   │                   Profile via CLS (SQL queries, HTTP calls, cache ops…)
   ▼
ProfilerInterceptor ── finalizes timing, runs CollectorRegistry.collectAll(),
   │                   lets context adapters enrich the Profile, persists it,
   │                   and injects the toolbar into HTML responses
   ▼
ProfilerStorageService → storage adapter (memory or file)
   │
   ▼
ProfilerController ─── serves the UI at /_profiler (list / detail / data),
                       protected by ProfilerGuard

The shared CLS context (nestjs-cls) is the backbone: the middleware puts the Profile there, and everything downstream — collectors, the logger adapter, ProfilerService — reads it back without threading the profile through method signatures.

Collectors

Each optional @eleven-labs/nest-profiler-* package is a self-contained NestJS module that does two things:

  1. Patches its host library (the TypeORM driver, the MikroORM logger, axios interceptors, the cache manager, ValidationPipe…) to append entries to the active profile. Patches are idempotent (__profilerPatched) so re-init never double-instruments.
  2. Exposes a panel via a provider annotated with @ProfilerCollector(). The CollectorRegistry auto-discovers these through Nest's DiscoveryService — no manual registration — and calls each collect() to build its panel data.

This is the extension seam: a custom collector is just a provider implementing IProfilerCollector. See Custom collectors.

Non-HTTP protocols

Protocols other than HTTP (GraphQL, gRPC, WebSockets…) are supported through IContextAdapter: an adapter recovers and enriches the profile for its context type, and the interceptor delegates to it automatically once it is registered via the PROFILER_CONTEXT_ADAPTERS multi-token. See Custom protocol adapters.

Common Commands

Run a task across every package via Turbo:

pnpm lint           # eslint
pnpm typecheck      # tsc --noEmit
pnpm test           # run unit tests
pnpm test:cov       # run tests with coverage (enforces the 90% threshold)
pnpm build          # build all packages
pnpm docs:dev       # serve the docs site
pnpm docker:up      # start Postgres + MongoDB for the example (docker:down to stop)
pnpm attw           # check published type resolution (Are the Types Wrong?)
pnpm changeset      # record a version bump

Target a single package with --filter:

pnpm --filter @eleven-labs/nest-profiler test:cov
pnpm --filter @eleven-labs/nest-profiler-typeorm build

Publishing

Packages are versioned with Changesets and released from CI to the public npm registry. The versioning policy (0.x rules, ALLOW_MAJOR_BUMPS), the stable release flow, and the alpha/beta prerelease runbook live in MAINTAINERS.md.

About

A Symfony Web Profiler-inspired toolkit for NestJS — profile every request with a rich panel UI. Powered & maintained by Eleven Labs.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors