Installation
Install the package, pick an entry point, and know which runtimes it runs on.
npm install @unhingged/logit
# or
bun add @unhingged/logit
# or
pnpm add @unhingged/logitThe package has no dependencies and ships ESM and CommonJS builds with TypeScript declarations. It is MIT licensed.
Entry points#
One package, five entry points. The root is isomorphic; the others import Node built-ins and are only loaded where you import them.
| Import | What it adds | Runs on |
|---|---|---|
@unhingged/logit | The logger, templates, capture, LogContext, enrichers, filters, formatters, the console / stream / memory / callback / HTTP / Seq sinks | Node, Bun, Deno, the Next.js edge runtime, browsers |
@unhingged/logit/node | fileSink, withMachineName, withProcessId, withProcessInfo, interceptConsole, closeOnExit — plus everything in the root | Node, Bun |
@unhingged/logit/next | withLogging, createOnRequestError, requestDiagnostics — plus everything in the root | Next.js (Node and edge runtimes) |
@unhingged/logit/express | requestLogger, errorLogger — plus everything in the root | Node, Bun |
@unhingged/logit/otel | otlpHttpSink, otelBridgeSink, encodeOtlpLogs — plus everything in the root | Anywhere with fetch |
Every subpath re-exports the root, so a Node application needs one import:
import { configure, consoleSink, fileSink, closeOnExit, log } from '@unhingged/logit/node';Runtimes#
- Node.js 20.16+ — the ambient context (
LogContext) rides onAsyncLocalStorage, found throughprocess.getBuiltinModulewithout anode:import in the root entry. Node 22 and 24 are the targets; 20.16 is the floor. - Bun and Deno — the same path; both expose
AsyncLocalStorage. - Next.js edge runtime —
@unhingged/logit/nextimportsAsyncLocalStoragefromnode:async_hooks, which the edge runtime provides, and installs it. Use that entry inmiddleware.ts. - Browsers — the root entry works as is. There is no
AsyncLocalStorage, soLogContextfalls back to a synchronous stack: properties pushed in a callback are visible inside it, not acrossawait. See Browser.
TypeScript#
Types come with the package. The using keyword for LogContext.push() and Operation needs TypeScript 5.2+ with "lib": ["esnext"] (or "esnext.disposable"); without it, call .dispose() / .abandon() yourself.
import type { LogEvent, Sink, Enricher, Filter, LoggerOptions } from '@unhingged/logit';What to read next#
The quick start gets a logger writing in a few lines. If you are coming from Serilog, For Serilog users maps every API you know. From pino or winston: migrating from pino, migrating from winston.