console.log is broken. better.log fixes it.
Zero Dependencies · 3.8KB Gzipped · 280 Tests · 96% Coverage · 8 Framework Integrations
You wouldn't debug a multi-step process with sticky notes. Stop debugging your app with console.log.
npm install @better-logger/core// console.log — flat noise, no structure
console.log('start')
console.log('user', user)
console.log('after db')
console.log('payment', payment)
console.log('done')And then trying to mentally reconstruct:
- What ran first?
- How long did each thing take?
- Where did it fail?
- What were the values at each step?
import { better } from '@better-logger/core'
// Same code. Better output.
better.log('start')
better.log('user', user)
better.log('after db')
better.log('payment', payment)
better.log('done')What you get:
🚀 [flow:default] (tid: abc123)
→ start
✓ start (12ms)
→ user
data: { email: "test@example.com" }
✓ user (45ms)
→ after db
✓ after db (210ms)
→ payment
data: { amount: 99.99 }
✓ payment (183ms)
→ done
✓ done (0ms)
🏁 [flow:default] success (450ms)
Automatic timing. Context propagation. Hierarchical grouping. Zero config.
| Feature | console.log | pino | winston | better.log |
|---|---|---|---|---|
| Drop-in replacement | — | ❌ | ❌ | ✅ |
| Auto-flow grouping | ❌ | ❌ | ❌ | ✅ |
| Automatic timing | ❌ | Manual | Manual | ✅ |
| Context propagation | ❌ | Manual | Manual | ✅ |
| Hierarchical output | ❌ | ❌ | ❌ | ✅ |
| Zero dependencies | ✅ | ❌ | ❌ | ✅ |
| Bundle size | 0KB | 30KB | 100KB | 8KB |
| TypeScript support | ❌ | ✅ | ✅ | ✅ |
| Browser support | ✅ | ❌ | ❌ | ✅ |
| Structured output | ❌ | ✅ | ✅ | ✅ |
| Auto-error tracking | ❌ | ❌ | ❌ | ✅ |
import { better } from '@better-logger/core'
// Before
console.log('User created:', user)
console.error('Payment failed:', error)
// After
better.log('User created:', user)
better.log.error('Payment failed:', error)better.log.info('Server started', { port: 3000 })
better.log.warn('Slow query', { duration: 250 })
better.log.error('Connection failed', error)const flow = better.flow('checkout', { tags: ['payment'] })
flow.setContext({ userId: 'user-123' })
const step = flow.step('charge-card', { amount: 99.99 })
const result = await paymentGateway.charge({ amount: 99.99 })
step.success(result)
flow.success()const flow = better.flow('data-export')
const data = await flow.run('fetch-data', async () => {
return await db.users.find({})
})
flow.success()better.log('message') // Simple message
better.log('message', data) // Message with data
better.log.warn('warning', data) // Warning (auto-tags flow)
better.log.error('error', error) // Error (fails flow)
better.flow('name', options) // Explicit flow
better.setEnabled(false) // Disable all logging
better.subscribe(fn) // Listen for flow completions
better.toJSON(flow) // Export flow as JSONbetter.log.toFile('app.log') // File transport
better.log.toStream(process.stdout) // Stream transport
better.log.toHttp('https://api.example.com/log') // HTTP transportbetter.log.redact(['password', 'ssn']) // PII redaction
better.log.async(true) // Non-blocking async
better.log.flush() // Force completebetter.setIdleTimeout(200) // Auto-complete timeout
better.setFlowName('my-app') // Default flow name
better.setDefaultTags(['app', 'v3']) // Tags on all flowsWe've included 11 comprehensive examples:
| Example | What it shows |
|---|---|
examples/01-express-rest-api.js |
Express middleware, CRUD, error handling |
examples/02-background-job-processor.js |
Job queue, retry logic, nested flows |
examples/03-authentication-flow.js |
Login, token refresh, password reset |
examples/04-ecommerce-order-processing.js |
Multi-step checkout, payments, shipping |
examples/05-cli-tool.js |
CLI commands, progress, dry-run |
examples/06-api-integration-client.js |
HTTP client, retry, rate limiting |
examples/07-microservice-distributed-tracing.js |
Trace context, downstream calls |
examples/08-testing-utilities.js |
Test runner, assertions, perf tests |
examples/09-data-pipeline.js |
ETL stages, transforms, aggregation |
examples/10-full-application.js |
Complete Node.js app with all patterns |
examples/11-angular-app.js |
Angular service, HTTP interceptor, error handler |
Framework integrations (13 total):
| Package | Framework | Install | When to use this vs Core |
|---|---|---|---|
@better-logger/express |
Express.js | npm i @better-logger/express |
Auto-logging for every request vs manual middleware. |
@better-logger/fastify |
Fastify | npm i @better-logger/fastify |
Plugin with hooks vs manual app.addHook. |
@package/koa |
Koa | npm i @better-logger/koa |
Middleware + error handler vs manual ctx logic. |
@better-logger/hono |
Hono (Edge) | npm i @better-logger/hono |
Edge-compatible middleware for Cloudflare/Vercel. |
@better-logger/nestjs |
NestJS | npm i @better-logger/nestjs |
Module + Interceptor + Exception filter integration. |
@better-logger/nextjs |
Next.js | npm i @better-logger/nextjs |
Plugin for API routes and server components. |
@better-logger/react |
React | npm i @better-logger/react |
Hooks for lifecycle and error boundaries. |
@better-logger/angular |
Angular | npm i @better-logger/angular |
Service + HTTP interceptor + error handler. |
@better-logger/vue |
Vue 2/3 | npm i @better-logger/vue |
Plugin + composable for lifecycle tracking. |
@better-logger/svelte |
Svelte | npm i @better-logger/svelte |
Function for component and async tracking. |
@better-logger/sveltekit |
SvelteKit | npm i @better-logger/sveltekit |
Server hook for routes and API endpoints. |
@better-logger/astro |
Astro | npm i @better-logger/astro |
Integration for build and dev server logging. |
@better-logger/cli |
CLI Tools | npm i @better-logger/cli |
Helpers for progress bars, tables, commands. |
| Metric | better.log | console.log | pino | winston |
|---|---|---|---|---|
| Simple message | 89ms | 45ms | 38ms | 120ms |
| With data | 142ms | 78ms | 65ms | 180ms |
| Async mode | 52ms | — | — | — |
| Bundle size | 8KB | 0KB | 30KB | 100KB |
better.log is fast enough for 95% of use cases. For high-throughput, use async mode.
See BENCHMARKS.md for full benchmarks.
npx @better-logger/codemod .Or manually: Replace console.log → better.log, console.error → better.log.error.
See Migration Guides, docs/MIGRATE-FROM-WINSTON.md.
| Metric | Value |
|---|---|
| Tests | 280 passing |
| Coverage | 96.61% |
| Bundle size | 10.73KB (3.8KB gzipped) |
| Dependencies | 0 |
| TypeScript | Full support |
| Runtimes | Node 18+, Browser, Edge |
| Package | Purpose |
|---|---|
@better-logger/core |
Core library |
packages/express/ |
Express middleware |
packages/fastify/ |
Fastify plugin |
packages/koa/ |
Koa middleware |
packages/hono/ |
Hono/Edge middleware |
packages/nestjs/ |
NestJS module |
packages/nextjs/ |
Next.js plugin |
packages/react/ |
React hooks |
packages/angular/ |
Angular service |
packages/vue/ |
Vue 2/3 plugin |
packages/svelte/ |
Svelte functions |
packages/sveltekit/ |
SvelteKit hooks |
packages/astro/ |
Astro integration |
packages/cli/ |
CLI helpers |
packages/eslint-plugin/ |
ESLint rules |
packages/vscode/ |
VS Code snippets |
- ❌ Log levels (debug, info, warn, error) — execution tracing ≠ log routing
- ❌ Transport layers — we emit data, you decide where it goes
- ❌ SaaS dashboards — we don't host your logs
- ❌ Auto-instrumentation — you control what gets traced
MIT