This is the whole learning curve.
Import the singleton and log. No factory to wire up, no context provider to mount, no environment checks. When you are ready for Datadog, pretty output, or request tracing, you opt in — the call sites never change.
Read the introimport { logger } from '@cues/sawdust/logger'
// Works the same in Node, the browser, and workers.
logger.info('checkout completed', { orderId, amountCents })
logger.error('payment failed', err, { orderId })
Everything a shared logging layer should be
Sawdust is the logging toolkit your monorepo keeps trying to build by hand — done once, correctly, and shared everywhere.
One API, every runtime
The same import and the same calls run in Node.js, the browser, and background workers. No per-environment logger, no #ifdefs, no drift.
Pluggable transports
Console, pretty terminal, Consola, Datadog logs, Datadog browser logs, and RUM — mix and match per environment. Built on LogLayer.
Configure once, upgrade in place
A singleton façade you can import before it is even configured. Bootstrap promotes it to a richer logger without breaking a single existing import.
Request-scoped context
AsyncLocalStorage on Node stamps every log inside a request with its requestId, userId, and route — automatically, with zero prop drilling.
Testing built in
Service-locator resets and a noop logger make suites deterministic. Swap in a mock, assert the calls, reset — no leaking global state.
Structured & safe
Round-trippable error serialization and context sanitization mean clean, queryable logs instead of stringified stack-trace soup.
Runtime coverage
One package. The right build resolves automatically.
| Capability | Node.js | Browser | Worker |
|---|---|---|---|
| Singleton façade + scoring | ✅ | ✅ | ✅ |
| Console / pretty / Consola | ✅ | ✅ | ✅ |
| Datadog server logs + APM trace injection | ✅ | — | ✅ |
| Datadog browser logs + RUM | — | ✅ | — |
| AsyncLocalStorage request scope | ✅ | stack emulation | ✅ |
Your future self is already using it.
Add one dependency, delete a folder of bespoke logger glue, and get consistent structured logs across every app you ship.