by micah

Pino is a very low overhead JSON logger for Node.js, offering 5x faster logging than alternatives with support for child loggers, transports, redaction, and web framework integrations.
Pino is a high-performance JSON logger for Node.js that serializes log records to a writable stream with minimal CPU overhead. It is designed for production Node.js services where log throughput matters, and supports child loggers, redaction, custom serializers, and worker-thread transports.
.github/ - CI workflows and repository automationdocs/ - Full documentation: API, transports, redaction, browser, pretty-printingdocsify/ - Sidebar configuration for the documentation siteexamples/ - Minimal runnable usage examples (basic.js, transport.js)lib/ - Internal modules: levels, symbols, tools, redaction, proto, transport, multistream, time, workerCONTRIBUTING.md - Contribution guidelinesLICENSE - MIT license textREADME.md - Project overview and quick-startSECURITY.md - Security policybin.js - CLI entry point for piping log outputbrowser.js - Browser-compatible build of Pinoeslint.config.js - ESLint configuration for the projectfile.js - Async helper that creates a ready file-destination streampino.d.ts - Full TypeScript type definitionspino.js - Main entry point; exports the pino factory and all utilitiestsconfig.json - TypeScript compiler options for type checkingnpm install user@example.com
# Pino bundles these; they install automatically as transitive deps:
# @pinojs/redact, atomic-sleep, on-exit-leak-free,
# pino-abstract-transport, pino-std-serializers,
# process-warning, quick-format-unescaped, real-require,
# safe-stable-stringify, sonic-boom, thread-stream
No native build steps, no pod install, no Android linking required.
source/ directory into your project root, e.g. vendor/pino/.package.json add a local alias so imports resolve cleanly:
{
"dependencies": {
"pino": "file:./vendor/pino"
}
}
Then run .Spin up an isolated sandbox and run it server-side — no local setup.
Tetrees AI Review of this version
This JavaScript library / package completed archive review. Structure, dependency manifests, documentation, functional source, and common risk patterns were checked by the Tetrees verification pipeline; runtime phases are stated separately.
Deterministic AVCP artifact review
Pipeline avcp-2026-08-04.1 · SHA-256 791aee41909859c9…
This version-scoped review deterministically inspects the submitted archive for structure, dependencies, documentation, functional source, and common malicious or high-risk signals. Build and test phases are reported as passed only after an isolated sandbox audition. It is not a guarantee of perfect security.
Reviewed Aug 4, 2026
Push this product straight into your AI IDE, web builder or cloud IDE.
Connect Tetrees to a compatible AI IDE, list products you own, and request the verified ZIP without exposing seller upload controls.
No reviews yet.
Sign in to join the discussion
Loading discussion…
npm installtsconfig.json includes the vendor types:
{
"compilerOptions": {
"typeRoots": ["./node_modules/@types", "./vendor/pino"],
"moduleResolution": "node"
}
}
LOG_LEVEL environment variable to control verbosity:
LOG_LEVEL=debug node server.js
pino-pretty separately and pipe:
node server.js | npx pino-pretty
import pino from 'pino'
function pino(opts?: pino.LoggerOptions, stream?: pino.DestinationStream): pino.Logger
function pino(stream?: pino.DestinationStream): pino.Logger
The main factory function. Call it once at application startup to obtain a root logger. Pass an options object to configure level, serializers, redaction, and message key. The returned Logger instance is the object you call .info(), .error(), etc. on.
pino.destination(opts?: string | number | SonicBoomOpts): SonicBoom
Creates a high-throughput SonicBoom writable stream. Pass a file path, file descriptor (default 1 = stdout), or an options object with dest and sync. Use this when you need non-blocking writes or want to target a file instead of stdout.
logger.child(bindings: Record<string, unknown>, options?: pino.ChildLoggerOptions): pino.Logger
Creates a new logger that inherits the parent's configuration and merges bindings into every log record it emits. Use child loggers to attach request-scoped context (e.g., requestId, userId) without manually threading fields through every log call.
pino.transport(opts: pino.TransportSingleOptions | pino.TransportMultiOptions): ThreadStream
Instantiates a worker-thread transport stream. Because Pino logs synchronously in the main thread and delegates I/O to the worker, this keeps the event loop free. Use it to write to remote sinks (Datadog, Elasticsearch, files) without blocking request handling.
Create a root logger and emit records at different levels. Fields from the options object appear on every line.
import pino from 'pino'
const logger = pino({
level: process.env.LOG_LEVEL || 'info',
base: { pid: process.pid, service: 'api' },
timestamp: pino.stdTimeFunctions.isoTime
})
logger.info('server started')
logger.warn({ port: 3000 }, 'listening on non-standard port')
logger.error(new Error('something broke'), 'unhandled error')
Attach a requestId to every log line within a single HTTP request without polluting the root logger.
import express from 'express'
import pino from 'pino'
import { randomUUID } from 'crypto'
const rootLogger = pino({ level: 'info' })
const app = express()
app.use((req, res, next) => {
req.log = rootLogger.child({ requestId: randomUUID(), method: req.method, url: req.url })
req.log.info('request received')
next()
})
app.get('/health', (req, res) => {
req.log.info('health check')
res.json({ status: 'ok' })
})
app.listen(3000)
Prevent secrets from appearing in logs by configuring the redact option.
import pino from 'pino'
const logger = pino({
level: 'info',
redact: {
paths: ['req.headers.authorization', 'user.password', '*.token'],
censor: '[REDACTED]'
}
})
logger.info({
user: { id: 42, password: 's3cr3t' },
req: { headers: { authorization: 'Bearer abc123' } }
}, 'login attempt')
// password and authorization are replaced with [REDACTED]
Offload file I/O to a worker thread to avoid blocking the main event loop.
import pino from 'pino'
const transport = pino.transport({
target: 'pino/file',
options: { destination: '/var/log/app.log', mkdir: true }
})
const logger = pino({ level: 'info' }, transport)
logger.info({ startup: true }, 'application boot')
logger.debug('this line only appears if level is debug or lower')
pino.js - Root module; constructs the logger factory, wires symbols, serializers, level helpers, and exports pino.destination, pino.transport, pino.multistream, and pino.stdSerializers.pino.d.ts - TypeScript declarations for the entire public API including Logger, LoggerOptions, TransportOptions, redactOptions, and all helper types.browser.js - Alternate entry point for browser bundles; replaces Node streams with console.* calls and provides a subset of the redaction API using @pinojs/redact.file.js - Async helper that constructs a SonicBoom destination and awaits its ready event before returning; used by the pino/file transport target.bin.js - CLI wrapper; used when Pino is invoked via node bin.js or piped scripts.lib/levels.js - Level validation, numeric mappings, cache generation, and comparison helpers.lib/symbols.js - Private Symbol keys used to store internal state on logger instances without polluting the public interface.lib/tools.js - Utility factories: buildSafeSonicBoom, asChindings, buildFormatters, stringify, createArgsNormalizer.lib/proto.js - The logger prototype; defines .child(), .bindings(), .flush(), .isLevelEnabled(), and the level setter/getter.lib/redaction.js - Wraps @pinojs/redact to integrate path-based censoring into the serialization pipeline.lib/transport.js - Implements pino.transport(); spawns a ThreadStream worker for async log delivery.lib/multistream.js - Implements pino.multistream(); fans log records out to multiple destinations.lib/time.js - Provides epochTime and nullTime timestamp functions; stdTimeFunctions re-exports these.lib/worker.js - Worker-side bootstrap that imports and runs the user-specified transport target inside the worker thread.lib/caller.js - Detects the calling module for diagnostic purposes.lib/constants.js - DEFAULT_LEVELS map and SORTING_ORDER enum.lib/meta.js - Exports the current package version string.lib/deprecations.js - Emits process-warning deprecation notices for removed options.lib/transport-stream.js - Low-level stream bridge between Pino's write path and the transport worker.examples/basic.js - Minimal hello-world usage.examples/transport.js - Demonstrates pino.transport() with a file target.import pino from 'pino' (Node resolves the default export automatically) and avoid named import { pino }.logger.flush() in a process.on('exit', ...) handler or use pino.destination({ sync: false }) with sonic-boom's flushSync.level set below 'info' is silently ignored in production builds: Always pass level explicitly; do not rely on the LOG_LEVEL env var being picked up unless you wire it yourself in options.bindings are serialized at child-creation time: Mutating the object passed to .child() after creation has no effect; pass a new object for each request.*): Bracket notation (user['password']) is not supported; use user.password instead.pino.js pulls in Node builtins; point your bundler to browser.js via the browser field in package.json or an alias, otherwise bundle size balloons.I have the Pino logger source at `vendor/pino/` and its integration guide at `USAGE.md`.
The upstream package is `user@example.com`.
Please integrate Pino into my project by doing the following steps:
1. Read `USAGE.md` and `vendor/pino/pino.d.ts` to understand the real API.
2. Create a `src/logger.ts` module that exports a root pino logger instance
configured with:
- level from process.env.LOG_LEVEL defaulting to 'info'
- isoTime timestamps
- redaction of ['req.headers.authorization', 'user.password']
- base fields: { service: '<my-service-name>' }
3. In my Express app (`src/app.ts`), add middleware that creates a child logger
per request with a unique requestId and attaches it to `req.log`.
4. Replace all existing `console.log` / `console.error` calls in `src/` with
the appropriate `req.log` or root logger calls.
5. Add a pino.transport() call writing to `logs/app.log` in non-development
environments.
6. Show me only the changed files with full content. Do not invent any Pino
API that is not present in `vendor/pino/pino.d.ts` or `USAGE.md`.
Pino is released under the MIT License (see source/LICENSE). Upstream repository: https://github.com/pinojs/pino. npm package: pino.
This product’s unique contribution is clean room implementation of valuable code block into AVCP compatible standard.
The full install guide and integration prompts unlock after purchase.
Automation, Utilities & Developer Tools
Free