logfx
v0.3.0
Published
Tiny, pretty logging for JS. Colors, emojis, namespaces. Zero deps.
Maintainers
Readme
logfx
Beautiful, colorful console logging with emojis, levels & namespaces
Features
- Colorful output with emoji prefixes
- Namespaces to organize logs by module
- Log levels —
debug,info,success,warn,error - Auto-silencing — debug logs hidden in production
- Timestamps — optional time display
- Context — attach metadata to all logs
- Field redaction — hide sensitive data automatically
- Log sampling — reduce log volume in production
- Async logging — buffer and batch logs for performance
- Universal — works in Node.js and browsers
- Tiny — zero dependencies, ~3KB gzipped
- TypeScript — full type support
Installation
npm install logfxQuick 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'))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 ...Errors include full stack traces when available.
Namespaced Loggers
import { logger } from 'logfx'
const authLog = logger('auth')
authLog.info('User login attempt') // 💡 INFO [auth] User login attempt
authLog.success('Login successful') // ✅ SUCCESS [auth] Login successfulOutput:
💡 INFO [auth] User login attempt
✅ SUCCESS [auth] Login successful
💡 INFO [database] Connecting...
✅ SUCCESS [database] ConnectedConfiguration
import { createLogger } from 'logfx'
const log = createLogger({
namespace: 'api',
level: 'warn', // only show warn and error
timestamp: true,
enabled: true,
})| Option | Type | Default | Description |
|--------|------|---------|-------------|
| namespace | string | - | Prefix for logs |
| level | LogLevel | 'debug' | Minimum level to display |
| timestamp | boolean | false | Show timestamps |
| enabled | boolean | true | Enable/disable logging |
| transports | Transport[] | - | Custom transports |
| context | object | - | Metadata added to all logs |
| redact | RedactOptions | - | Field redaction config |
| sampling | SamplingOptions | - | Log sampling rates |
| async | boolean | false | Enable async buffered logging |
| buffer | BufferOptions | - | Buffer size and flush interval |
Transports
Send logs to multiple destinations:
import { createLogger, transports } from 'logfx'
const log = createLogger({
transports: [
transports.console({ format: 'pretty' }),
transports.file({ path: './logs/app.log' }),
transports.webhook({ url: 'https://your-api.com/logs' }),
]
})JSON Output
For production, use JSON format:
const log = createLogger({
transports: [
transports.console({ format: 'json' })
]
})
log.info('User login', { userId: 123 })
// {"timestamp":"2025-12-17T...","level":"info","message":"User login","userId":123}File transport format option:
transports.file({
path: './logs/app.log',
format: 'json' // or 'pretty' for plain text (default: 'json')
})Available Transports
| Transport | Description |
|-----------|-------------|
| console | Pretty or JSON output to stdout |
| file | Write to file (Node.js only) |
| webhook | POST logs to HTTP endpoint |
Webhook Transport Options
transports.webhook({
url: 'https://your-api.com/logs',
method: 'POST', // default, or 'PUT'
headers: { 'Authorization': 'Bearer token' },
batchSize: 10, // default: 10 logs per batch
flushInterval: 5000, // default: 5 seconds
maxBufferSize: 100, // default: 10x batchSize, drops oldest when full
timeout: 30000 // default: 30 seconds
})Batches are sent automatically when full or on the flush interval. Oldest logs are dropped if the buffer exceeds maxBufferSize.
Context
Attach metadata to all logs from a logger:
const log = createLogger({
context: {
service: 'api-gateway',
version: '1.2.0',
env: process.env.NODE_ENV
},
transports: [transports.console({ format: 'json' })]
})
log.info('Request received', { path: '/users' })
// {"service":"api-gateway","version":"1.2.0","env":"production","path":"/users",...}Child loggers inherit and can extend context:
const requestLog = log.child('request', {
context: { requestId: 'req-123' }
})
requestLog.info('Processing')
// Includes service, version, env, AND requestIdField Redaction
Automatically hide sensitive data:
const log = createLogger({
redact: {
keys: ['password', 'token', 'apiKey'],
paths: ['user.email', 'config.secret'],
censor: '[HIDDEN]' // default: '[REDACTED]'
},
transports: [transports.console({ format: 'json' })]
})
log.info('User login', { username: 'john', password: 'secret123' })
// {"username":"john","password":"[HIDDEN]",...}Log Sampling
Reduce log volume by sampling:
const log = createLogger({
sampling: {
debug: 0.1, // 10% of debug logs
info: 0.5, // 50% of info logs
warn: 1.0, // 100% of warnings
error: 1.0 // 100% of errors (never sample errors)
},
transports: [transports.console()]
})Async Logging
Buffer logs and flush in batches for better performance:
const log = createLogger({
async: true,
buffer: {
size: 100, // flush after 100 logs
flushInterval: 5000 // or every 5 seconds
},
transports: [transports.file({ path: './app.log' })]
})
// Graceful shutdown
process.on('SIGTERM', async () => {
await log.flush()
await log.close()
process.exit(0)
})Extended Features
Import only what you need:
import { box, table, diff, time, timeEnd, badge } from 'logfx'| Import | Size | What it does |
|--------|------|--------------|
| Core (log) | ~2 KB | Basic logging |
| time/timeEnd | +80 bytes | Performance timing |
| box | +350 bytes | ASCII boxes for banners |
| table | +300 bytes | Pretty-print data tables |
| diff | +450 bytes | Compare objects |
| Everything | ~3.4 KB | All features |
Timers
time('api-call')
await fetchData()
timeEnd('api-call') // ⏱️ api-call: 245.32msBoxes
box('Server Started!', { title: '🚀 My App', borderColor: 'green' })╭─ 🚀 My App ─────────────────╮
│ Server Started! │
╰─────────────────────────────╯Tables
import { table } from 'logfx'
const users = [
{ name: 'John', role: 'Admin', active: true },
{ name: 'Jane', role: 'User', active: false },
]
table(users)Output:
┌─────────┬─────────┬─────────┐
│ name │ role │ active │
├─────────┼─────────┼─────────┤
│ John │ Admin │ true │
│ Jane │ User │ false │
└─────────┴─────────┴─────────┘Diff
diff({ name: 'John', age: 25 }, { name: 'Jane', age: 25, email: '[email protected]' })Changes:
~ name: "John" → "Jane"
+ email: "[email protected]"All-in-One
import { createExtendedLogger } from 'logfx'
const log = createExtendedLogger()
log.box('Ready!')
log.table(data)
log.diff(before, after)API
// Core
log.debug(...args)
log.info(...args)
log.success(...args)
log.warn(...args)
log.error(...args)
log.child(namespace, options?)
log.setEnabled(bool)
log.setLevel(level)
log.flush() // flush buffered logs
log.close() // flush and close transports
// Extended
time(label) / timeEnd(label)
count(label) / countReset(label)
group(label) / groupEnd()
assert(condition, ...args)
box(message, options?)
table(data)
diff(before, after, label?)
badge(text, color?)License
MIT
