spawntrail
Logs without context are noise: 'payment failed' means nothing without the request id, user, and route beside it. spawntrail keeps a per-request context with AsyncLocalStorage and injects it into every log line at write time, through the logger's own hook (a winston format, a pino mixin), so you set context once at the edge and it appears everywhere downstream without threading a logger through your call stack. It is the third version of an idea I first shipped in 2021 as a singleton (which bled between concurrent requests) and then as an AsyncLocalStorage proof of concept (which froze the context at request start). spawntrail is the successor to both, and express-session-logger is deprecated in its favor.
# why i built this
I wanted MDC-style contextual logging (set context once, have it stamp every log line) without a global singleton bleeding requests together or being locked to one logger. It took two wrong versions in 2021 to arrive at injecting the context at log time through each logger's own hook.
# key features
One AsyncLocalStorage isolates each request's context across every async hop: the 50-interleaved-scopes concurrency test the earlier singleton could never pass.
winston() and pino() hooks stamp the live context onto each record as it is written, so context added mid-request appears in later logs.
Any logger with a format, mixin, or .child hook; any framework via run(bindings, fn). It feeds the logger you already have instead of replacing it.
# highlights
- AsyncLocalStorage core: per-request context isolated across every await, no singleton, no cls-hooked
- Injects at log time via the logger's own hook: winston() format, pino() mixin, bind() fallback
- MDC put/get/del with dot-paths; nested scopes act as segments
- Logger- and framework-agnostic: express middleware plus a plain run() for fastify, koa, or workers
- Zero dependencies, TypeScript-first, ESM + CJS + types, ~6 KB
# built with
# more work
AbakoJS
Zero-dependency monetary arithmetic for JS & TS. Precise rounding, fee and discount calculation, value partitioning and crypto asset support.
DdbFlow
Fluent, type-safe DynamoDB params builder. Kill the ExpressionAttributeNames/Values boilerplate without adopting an ORM. Zero dependencies, AWS SDK v2 and v3.