DEV Community

Chintan Shah
Chintan Shah

Posted on

logfx v0.5.0: From Dev Tool to Production Logger

Last month, I shared logfx. Since then, I've been using it in my projects and kept adding features I needed. v0.5.0 is the result - 15+ new features that make it production-ready.

Express Middleware

This was the most requested feature. Automatic request logging with timing and request IDs:

import express from 'express'
import { expressLogger } from 'logfx'

const app = express()
app.use(expressLogger())

app.get('/users', (req, res) => {
  req.log.info('Fetching users', { userId: req.query.id })
  res.json({ users: [] })
})
Enter fullscreen mode Exit fullscreen mode

Output:

💡 INFO [http] Incoming request { method: 'GET', path: '/users', requestId: 'abc123' }
💡 INFO [http] Fetching users { userId: '42' }
💡 INFO [http] Request completed { method: 'GET', path: '/users', status: 200, durationMs: 45 }
Enter fullscreen mode Exit fullscreen mode

You get req.log scoped to each request, automatic timing, and request IDs for tracing. Status codes automatically set the log level (5xx = error, 4xx = warn).

Options:

  • Skip routes (health checks)
  • Custom request ID extraction
  • Configurable headers

Fastify and Next.js Too

// Fastify
import Fastify from 'fastify'
import { fastifyLogger } from 'logfx'

const app = Fastify()
app.register(fastifyLogger())

app.get('/api/data', async (request, reply) => {
  request.log.info('Processing')
  return { ok: true }
})
Enter fullscreen mode Exit fullscreen mode
// Next.js
import { withLogging } from 'logfx'

export default withLogging(async (req, res) => {
  req.log.info('API called', { path: req.url })
  res.json({ ok: true })
})
Enter fullscreen mode Exit fullscreen mode

Color Themes

Added dracula and monokai themes because the default colors weren't great on every terminal:

import { createLogger } from 'logfx'

const log = createLogger({ theme: 'dracula' })
// or 'monokai', 'default'

log.info('Themed output')
log.success('Looks great')
log.error('Easy to spot')
Enter fullscreen mode Exit fullscreen mode

Makes logs easier to scan when you're debugging at 2am.

File Rotation

Logs now rotate automatically when they hit a size limit:

import { createLogger, transports } from 'logfx'

const log = createLogger({
  transports: [
    transports.file({
      path: './logs/app.log',
      rotation: {
        maxSize: '10mb',
        maxFiles: 5,
        compress: true  // gzip old files
      }
    })
  ]
})
Enter fullscreen mode Exit fullscreen mode

Creates app.log.1, app.log.2, etc. Old files get gzipped. No more disk space issues.

Issue Detection

This catches mistakes I kept making:

const log = createLogger({ detectIssues: true })

log.info('User data', { data: undefined })
// ⚠️ Warning: undefined value in log data

log.info('Auth', { password: 'secret123' })
// ⚠️ Warning: potential password in log data
Enter fullscreen mode Exit fullscreen mode

Only runs in development. Saved me from logging passwords to production a few times already.

Format Auto-Detection

Pretty output in dev, JSON in production. No config needed:

// Development (NODE_ENV=development)
log.info('Server started')
// 💡 INFO Server started (pretty, colored)

// Production (NODE_ENV=production)
log.info('Server started')
// {"timestamp":"2026-01-19T...","level":"info","message":"Server started"}
Enter fullscreen mode Exit fullscreen mode

Request ID Tracking

Built-in for tracing requests across your logs:

const log = createLogger({ requestId: 'req-123' })
log.info('Processing payment')
// Includes requestId in output for correlation
Enter fullscreen mode Exit fullscreen mode

Great for debugging issues across microservices.

Better Error Serialization

Stack traces are readable in dev, structured in prod:

try {
  await connectDatabase()
} catch (error) {
  log.error('Connection failed', error)
}
Enter fullscreen mode Exit fullscreen mode

Development output:

🔴 ERROR Connection failed
Error: Timeout
    at Database.connect (/app/db.js:45:11)
    at Server.start (/app/server.js:12:5)
Enter fullscreen mode Exit fullscreen mode

Production output:

{
  "timestamp": "2026-01-19T13:45:00.000Z",
  "level": "error",
  "message": "Connection failed",
  "error": {
    "message": "Timeout",
    "stack": "Error: Timeout\n    at Database.connect...",
    "code": "ETIMEDOUT"
  }
}
Enter fullscreen mode Exit fullscreen mode

Service Context

Automatically reads service metadata from environment:

// Reads SERVICE_NAME, SERVICE_VERSION, NODE_ENV
const log = createLogger()
log.info('Started')

// Output includes:
// {"service":"my-api","version":"1.0.0","environment":"production",...}
Enter fullscreen mode Exit fullscreen mode

Structured JSON Output

Production-ready JSON format for log aggregation tools:

const log = createLogger({ format: 'json' })
log.info('User login', { userId: 123 })
// {"timestamp":"2026-01-19T...","level":"info","message":"User login","data":{"userId":123}}
Enter fullscreen mode Exit fullscreen mode

Works with Datadog, Splunk, ELK stack, and other log aggregation tools.

Field Redaction

Hide sensitive data automatically:

const log = createLogger({
  redact: {
    fields: ['password', 'token', 'apiKey'],
    replacement: '***REDACTED***'
  }
})

log.info('User login', { 
  username: 'john', 
  password: 'secret123' 
})
// Output: { username: 'john', password: '***REDACTED***' }
Enter fullscreen mode Exit fullscreen mode

Log Sampling

Reduce log volume in high-traffic scenarios:

const log = createLogger({
  sampling: {
    debug: 0.1,  // 10% of debug logs
    info: 0.5,   // 50% of info logs
    error: 1.0   // 100% of errors (always log)
  }
})
Enter fullscreen mode Exit fullscreen mode

Useful when you're getting millions of requests.

Async Logging

Buffer and batch logs for better performance:

const log = createLogger({
  async: true,
  buffer: {
    size: 100,        // flush after 100 logs
    flushInterval: 1000  // or every 1 second
  }
})
Enter fullscreen mode Exit fullscreen mode

Prevents logging from blocking your event loop.

Multiple Transports

Send logs to different destinations simultaneously:

import { createLogger, transports } from 'logfx'

const log = createLogger({
  transports: [
    transports.console({ format: 'pretty' }),
    transports.file({ 
      path: './logs/app.log',
      format: 'json'
    }),
    transports.webhook({ 
      url: 'https://logs.example.com/ingest',
      batchSize: 10
    })
  ]
})
Enter fullscreen mode Exit fullscreen mode

Webhook Transport

Send logs to remote endpoints:

transports.webhook({
  url: 'https://logs.example.com',
  method: 'POST',
  headers: { 'Authorization': 'Bearer token' },
  batchSize: 10,
  flushInterval: 5000
})
Enter fullscreen mode Exit fullscreen mode

Great for custom log aggregation services or alerting systems.

Environment Detection

Automatically adapts to your environment:

  • CI/CD: Auto-disables colors
  • TTY Detection: Only shows colors in terminals
  • NO_COLOR/FORCE_COLOR: Respects standard env vars
  • NODE_ENV: Auto-switches format (pretty in dev, JSON in prod)

Complete Feature List

Core Logging:

  • 5 log levels (debug, info, success, warn, error)
  • Namespaced loggers
  • Colorful output with emojis
  • Timestamps
  • Context metadata

Production Features:

  • Format auto-detection (pretty/JSON)
  • Structured JSON output
  • Request ID tracking
  • Service context
  • Error serialization with stack traces
  • Field redaction
  • Log sampling
  • Async buffered logging

Transports:

  • Console transport
  • File transport with rotation
  • Webhook transport
  • Multiple transports simultaneously

Framework Integration:

  • Express middleware
  • Fastify plugin
  • Next.js API middleware

Developer Experience:

  • Color themes (default, dracula, monokai)
  • Issue detection (undefined values, passwords)
  • Environment detection (CI/CD, TTY)
  • TypeScript support
  • Zero dependencies

Why I Built This

I got tired of choosing between pretty logs in dev and structured logs in prod. Most loggers force you to pick one. logfx does both automatically.

Also wanted something that works in browsers and Node without extra config. Zero dependencies means no supply chain issues.

The middleware was the big one though. Every project needs request logging and I was copy-pasting the same code everywhere.

What Makes logfx Different

Works everywhere

One logger for your entire stack:

  • Node.js, Bun, Deno
  • Browsers (Chrome, Firefox, Safari)
  • Express, Fastify, Next.js
  • Edge runtimes (coming in v0.6.0)

Zero dependencies

No supply chain risk. No version conflicts. No security audits for logging dependencies.

Lightweight but feature-complete

  • ~11KB gzipped (46KB uncompressed)
  • Full TypeScript support
  • 117 passing tests
  • All the features you need, none you don't

Installation

npm install logfx
Enter fullscreen mode Exit fullscreen mode

Quick Start

import { log } from 'logfx'

log.debug('Debugging info', { detailed: true })
log.info('Server started', { port: 3000 })
log.success('User created')
log.warn('Memory usage high', { usage: '85%' })
log.error('Connection failed', new Error('Timeout'))
Enter fullscreen mode Exit fullscreen mode

Output:

🔍 DEBUG   Debugging info { detailed: true }
💡 INFO    Server started { port: 3000 }
✅ SUCCESS User created
⚠️ WARN    Memory usage high { usage: '85%' }
🔴 ERROR   Connection failed Error: Timeout
    at ...
Enter fullscreen mode Exit fullscreen mode

Try It

npm install logfx@0.5.0
Enter fullscreen mode Exit fullscreen mode

Links:


Top comments (0)