Powered & maintained by Eleven Labs
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.
Each package is a self-contained NestJS module with its own README:
@eleven-labs/nest-profiler— Core + Timeline panel@eleven-labs/nest-profiler-typeorm— Database panel (TypeORM)@eleven-labs/nest-profiler-mikro-orm— Database panel (MikroORM)@eleven-labs/nest-profiler-axios— HTTP Client panel@eleven-labs/nest-profiler-cache— Cache panel@eleven-labs/nest-profiler-auth— Security panel@eleven-labs/nest-profiler-config— Config panel@eleven-labs/nest-profiler-mongoose— Database (NoSQL) panel@eleven-labs/nest-profiler-validator— Validator panel@eleven-labs/nest-profiler-commander— Command panel (CLI / nest-commander)
Full guides and API reference live on the documentation site (pnpm docs:dev, then http://localhost:3002).
![]() |
![]() |
![]() |
| Database (TypeORM) | HTTP Client (Axios) | Cache |
![]() |
![]() |
![]() |
| Security (JWT/Auth) | Validator (class-validator) | Timeline (spans) |
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:3002To 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:devPackages are published to the public npm registry — install them like any other dependency, no authentication required:
pnpm add @eleven-labs/nest-profiler nestjs-clsimport { 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-typeormimport { TypeOrmCollectorModule } from '@eleven-labs/nest-profiler-typeorm';
@Module({
imports: [TypeOrmCollectorModule.forRoot({ slowQueryThreshold: 50 })],
})
export class ProductsModule {}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
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.
ProfilerModule.forRoot() resolves enabled synchronously and registers one of
two layers:
- Active (default) — mounts the middleware, the global interceptor, the
/_profilercontroller, the collector registry and storage. - Inert (
enabled: false) — registers onlyProfilerService, as a no-op. It stays injectable everywhere, so application code that callsprofiler.startSpan(...)orprofiler.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
│
▼
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.
Each optional @eleven-labs/nest-profiler-* package is a self-contained NestJS
module that does two things:
- 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. - Exposes a panel via a provider annotated with
@ProfilerCollector(). TheCollectorRegistryauto-discovers these through Nest'sDiscoveryService— no manual registration — and calls eachcollect()to build its panel data.
This is the extension seam: a custom collector is just a provider implementing
IProfilerCollector. See Custom collectors.
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.
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 bumpTarget a single package with --filter:
pnpm --filter @eleven-labs/nest-profiler test:cov
pnpm --filter @eleven-labs/nest-profiler-typeorm buildPackages 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.






