Browser-first · Node.js ready · Worker transport

Console

Structured, namespaced logging built for the browser and Node.js. Worker transport keeps your main thread free. Child loggers, configurable timestamps, and flexible transports — all in ~10 KB with zero dependencies.

Installation

npmnpm install konsole-logger
yarnyarn add konsole-logger
pnpmpnpm add konsole-logger

Interactive Demo

Namespace
Child Logger
Log Level
Controls

Output

live output0 lines
Click a log level above to start →
Printoff
ActiveApp
Childoff
Buffered0 entries

How it Works

Console works in browser and Node.js. It automatically picks the best output format for each environment. In browsers, logs are stored in a circular buffer for DevTools inspection. In Node.js, disabled levels add zero overhead — no buffer, no allocations.

📊
Structured logging
Every entry carries msg, fields, level, levelValue, namespace and timestamp — compatible with Datadog, Loki, and any log aggregator.
🏷️
Child loggers
logger.child({ requestId }) creates an ephemeral child that injects context into every line it produces. Bindings accumulate through nesting.
⏱️
Configurable timestamps
Full date+time by default. Presets: ISO 8601, epoch seconds/ms, time-only. Custom functions. Nanosecond precision via highResolution. Change format at runtime.
🎨
Auto formatting
TTY terminal → ANSI pretty. Pipe / CI → NDJSON. Browser → styled %c badges. One format: 'auto' option handles it all.
🔒
Field redaction
Mask sensitive data with redact: ['password', 'req.headers.authorization']. Applied before output, transports, and buffer. Children inherit parent paths. Disable at runtime in browser DevTools for debugging.
🚚
Transports
HttpTransport, FileTransport (with rotation + gzip), StreamTransport, ConsoleTransport. Add multiple to one logger. Filter and transform per transport.
🧵
Worker transport
useWorker: true moves log storage and HTTP batching off the main thread — Web Worker in browsers, worker_threads in Node.js. Your app never blocks on logging, even at high volume.
💾
In-browser log history
Circular buffer stores logs in memory for DevTools inspection via getLogs() and exposeToWindow(). In Node.js, buffer is off by default for maximum throughput.
Fast & lightweight
~10 KB gzipped, zero dependencies. On par with Pino on overhead, faster on JSON serialization, and significantly faster than Winston and Bunyan — at 1/3 the bundle size.

Benchmarks

Measured on Apple M2 Max, Node.js v23, 100K iterations. Pino, Winston, and Bunyan are Node.js only — Console works in both browser and Node.js. Run npm run benchmark to reproduce.

Throughput (ops/sec, higher is better)
ScenarioConsolePinoWinstonBunyan
Silent / disabled~8M~7M~1.5M
JSON → /dev/null~650K~470K~270K~340K
Child (disabled)~17M~14M~2M
Browser + buffer~4.7M
With Workernon-blocking
Bundle & Install Size (smaller is better)
ConsolePinoWinstonBunyan
Bundle (gzip)~10 KB~32 KB~70 KB~45 KB
Install size86 KB1.17 MB360 KB212 KB
Dependencies011110

Pino, Winston, and Bunyan are Node.js only. Console is the only structured logger that works in both browser and Node.js with worker offloading for non-blocking transport processing. See the Performance Guide for details.

Code Snippets

Six numeric log levels — discard everything below your threshold.

const logger = new Konsole({
  namespace: 'App',
  level: 'info',    // trace + debug discarded
});

logger.trace('→ entering loop');   // 10 — dropped
logger.debug('Cache miss');         // 20 — dropped
logger.info('Server started', { port: 3000 }); // 30 ✅
logger.warn('Memory at 80%');       // 40 ✅
logger.error(new Error('timeout')); // 50 ✅
logger.fatal('Out of memory');      // 60 ✅

Usage Examples

Console has no framework dependency — it works everywhere: React, plain HTML, and Node.js servers.

Import as a module in any React app — works with Next.js, Vite, and CRA.

import { Konsole } from 'konsole-logger';

// Create loggers at module level
const logger = new Konsole({ namespace: 'App', format: 'silent' });
const api    = new Konsole({ namespace: 'API', level: 'warn' });

function Dashboard() {
  const handleClick = () => {
    const req = logger.child({ requestId: crypto.randomUUID() });
    req.info('Dashboard loaded', { userId: 42 });
  };

  return <button onClick={handleClick}>Load</button>;
}

// Expose for DevTools debugging
Konsole.exposeToWindow();
Buffer
Level
Namespace
No entries match the current filter
Showing: 0Total: 0
Press Esc to close