Build on top of evlog
Everything you build on top of evlog falls on one of four axes in the data flow, plus a fifth transverse axis for code you want to share between projects.
┌─────────────────────┐
│ SOURCES │ How events enter
│ (frameworks, │ the pipeline
│ custom middleware)│
└──────────┬──────────┘
│
▼
┌─────────────────────┐
OBSERVERS │ PIPELINE │ What happens to them
(read-only: ◀────────│ (plugins, │ on the way through
streams, fs reader) │ enrichers, │
│ sampling) │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ SINKS │ Where they go
│ (drains: Axiom, │
│ Datadog, fs, …, │
│ custom) │
└─────────────────────┘
SHARED PACKAGES (catalogs, drains, enrichers, integrations
packaged as reusable npm libraries — orthogonal to all four axes)
I want to…
| Question | Answer |
|---|---|
| Add a service that receives my logs (Axiom, an internal API…) | Custom drains |
| Tint events with my own context (tenant id, deploy id, region…) | Custom enrichers |
| Decide live whether to keep an event based on the request outcome | Tail sampling |
| React to specific events (alert, side-effect, tracing) | Plugins |
| Combine several drains with retry, batching, fanout | Drain pipeline |
| See events live while I dev | Stream server |
| Subscribe in-process from a script or test | Stream API |
| Replay or tail historic logs | FS reader |
| Identify my evlog traffic on the receiver side | Identity headers |
| Support a framework that's not in the list | Custom framework |
| Share an error vocabulary between several services | Catalogs as packages |
| Build a quick local devtool | Local debugging toolkit |
| Handle multi-tenant context everywhere | Tenant-aware logging |
| Wire compliance-grade auditing | Compliance audit |
By stage of your app
| Stage | Typical needs | Pages |
|---|---|---|
| Solo / hobby — one app, local dev | Live events while debugging, log replay | Stream server, FS reader, Local debugging toolkit |
| Small team — one app in production | Send to a provider, redact PII, tag traffic | Sinks overview, Identity headers |
| Scale — single product, real prod | Custom enrichers, tail sampling, plugins, multi-drain fanout | Pipeline overview, Sinks overview, Tenant-aware logging |
| Platform — N apps sharing infra | Shared catalogs, custom drains/enrichers/integrations as npm packages | Shared packages |
By axis
Sources — how events enter
evlog/<framework> middlewares plug HTTP requests into the pipeline. When you write your own framework support (a new HTTP runtime, a CLI driver, a queue worker), you live here.
Pipeline — what happens during
Plugins, enrichers, sampling rules, redaction custom — anything that transforms or decides about an event between emit and drain.
Sinks — where events go
Built-in drain adapters (Axiom, Datadog, fs, …) plus the building blocks to write your own: defineDrain(), defineHttpDrain(), the drain pipeline (batch + retry + fanout), and identity headers.
Observers — read the flow
Subscribe to wide events without altering the pipeline. In-process pub/sub primitive, network SSE bridge, fs replay/tail, and concrete consumer recipes.
Shared — package for others
Turn a catalog, a drain, an enricher, or a framework integration into an npm package others can install. Same pattern for each : a small bit of typed code + module augmentation.
A note on serverless
The in-process stream and the stream server work everywhere a Node-like long-lived process runs — local dev, self-hosted servers, containers (Fly, Railway, Coolify), VMs.
They do not work on serverless platforms (Vercel Functions, Cloudflare Workers, AWS Lambda) because each invocation is an isolated process. Use a real broker (Redis Streams, NATS, Pub/Sub) for cross-instance fan-out in those environments.
The fs reader, identity headers, and the entire Pipeline / Sinks / Shared axes work everywhere — they are not bound to a long-lived process.
Custom Integration
Build your own evlog framework integration using the toolkit API — defineFrameworkIntegration, createMiddlewareLogger, AsyncLocalStorage, and the full drain/enrich/keep pipeline.
Overview
Observers read what flows through the pipeline without altering it — in-process subscribe, network SSE bridge, fs replay, recipes for browser tabs and CLIs.