npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@igniter-js/logger

v0.1.0

Published

Pino-based logger abstraction for Igniter.js

Readme

@igniter-js/logger

High-performance logging for Igniter.js applications powered by Pino.

Note: HTTP transport currently uses a fallback implementation. For production HTTP logging, use external Pino transports like @axiomhq/pino or @logtail/pino.

Features

  • Zero Pino API exposure - Work with Igniter abstractions
  • High performance - Built on Pino (5-10x faster than alternatives)
  • Built-in transports - Console, File, HTTP out of the box
  • External transport support - Use any Pino transport (pino-pretty, @logtail/pino, etc.)
  • Type-safe child loggers - Scoped context with full type inference
  • Pretty dev logging - Colorized, human-readable logs by default
  • Production-ready - File rotation, batching, remote logging
  • Server-only - Protected from browser imports

Installation

npm install @igniter-js/logger
# or
pnpm add @igniter-js/logger
# or
yarn add @igniter-js/logger
# or
bun add @igniter-js/logger

Quick Start

import { IgniterLogger } from "@igniter-js/logger";

// Create logger (default: pretty console logging)
const logger = IgniterLogger.create().build();

// Log messages
logger.info("Application started");
logger.error("Something went wrong", { errorCode: 500 });
logger.success("Deployment completed");

Why @igniter-js/logger

  • Consistent log structure across Igniter packages
  • Transport-first design with safe defaults for development
  • Context everywhere with base context, scoped children, and payloads
  • Server-only safety to prevent accidental browser usage

Core Concepts

Builder (IgniterLogger)
	-> Transport configuration
	-> Context and level defaults
	-> build()
				|
				v
Manager (IgniterLoggerManager)
	-> Log methods (info/warn/error/etc.)
	-> Child loggers
	-> Runtime controls (setLevel/flush)

Builder API

Basic Configuration

import { IgniterLogger, IgniterLogLevel } from "@igniter-js/logger";

const logger = IgniterLogger.create()
	.withLevel(IgniterLogLevel.Debug)
	.withAppName("my-api")
	.withComponent("auth")
	.withContext({ version: "1.0.0" })
	.build();

Built-in Transports

Console Transport

const logger = IgniterLogger.create()
	.addTransport({
		target: "console",
		options: {
			pretty: true, // Pretty formatting (default: true)
			colorize: true, // Colors (default: true)
		},
	})
	.build();

File Transport

const logger = IgniterLogger.create()
	.addTransport({
		target: "file",
		options: {
			path: "/var/log/app.log",
			mkdir: true, // Create directory if missing
			rotation: {
				maxSizeBytes: 10_000_000,
				maxFiles: 10,
				intervalMs: 86_400_000,
			},
		},
	})
	.build();

HTTP Transport

const logger = IgniterLogger.create()
	.addTransport({
		target: "http",
		options: {
			url: "https://logs.myapp.com/ingest",
			headers: { "X-API-Key": process.env.LOG_API_KEY ?? "" },
			batchSize: 100,
			timeoutMs: 10_000,
		},
	})
	.build();

Note: The current HTTP transport resolver maps to a Pino file target internally. HTTP delivery is not implemented yet. Track updates in AGENTS.md.

External Transports

Use any Pino transport from the ecosystem:

// npm install pino-pretty
const logger = IgniterLogger.create()
	.addTransport({
		target: "pino-pretty",
		options: {
			colorize: true,
			translateTime: "SYS:standard",
		},
	})
	.build();

Type-Safe Scoped Loggers

const logger = IgniterLogger.create()
	.defineScopes<{
		http: { requestId: string; method: string };
		jobs: { jobId: string; queueName: string };
	}>()
	.build();

// ✅ Type-safe
const httpLogger = logger.child("http", {
	requestId: "req-123",
	method: "POST",
});

// ❌ Type error: missing "method"
const invalid = logger.child("http", { requestId: "req-123" });

Manager API

Log Levels

logger.fatal("Critical system failure");
logger.error("Request failed", { statusCode: 500 });
logger.warn("Deprecated API usage");
logger.info("User logged in", { userId: "123" });
logger.debug("Cache hit", { key: "user:123" });
logger.trace("Function entry", { args: [1, 2, 3] });

Custom Methods

// Success logging
logger.success("Deployment completed");

// Grouping
logger.group("Processing batch");
logger.info("Item 1");
logger.info("Item 2");
logger.groupEnd();

// Separator
logger.separator();

Child Loggers

const httpLogger = logger.child("http", {
	requestId: "req-123",
	method: "POST",
});

httpLogger.info("Request received");
// Logs: { component: "http", requestId: "req-123", method: "POST", msg: "Request received" }

Runtime Controls

import { IgniterLogLevel } from "@igniter-js/logger";

// Change log level at runtime
logger.setLevel(IgniterLogLevel.Debug);

// Update app name (does not retroactively update Pino base)
logger.setAppName("new-name");

// Flush buffered logs
await logger.flush();

API Reference

Builder Methods

  • IgniterLogger.create()
  • withLevel(level: IgniterLogLevel)
  • withAppName(appName: string)
  • withComponent(component: string)
  • withContext(context: Record<string, unknown>)
  • addTransport(transport: IgniterTransportConfig)
  • defineScopes<T>()
  • build()

Manager Methods

  • log(level, message, context?, error?)
  • fatal(message, error?)
  • error(message, error?)
  • warn(message, ...args)
  • info(message, ...args)
  • debug(message, ...args)
  • trace(message, ...args)
  • success(message, ...args)
  • group(name?)
  • groupEnd()
  • separator()
  • child(componentName, context?)
  • setLevel(level)
  • setAppName(appName)
  • setComponent(componentName)
  • flush()

Types

  • IgniterLogLevel (enum)
  • IgniterTransportTarget ("console" | "file" | "http" | string)
  • IgniterTransportConfig<TOptions>
  • ConsoleTransportOptions
  • FileTransportOptions
  • HttpTransportOptions

Log Level Enum

import { IgniterLogLevel } from "@igniter-js/logger";

const level = IgniterLogLevel.Info;

Transport Options

| Transport | Option | Type | Description | | --- | --- | --- | --- | | Console | colorize | boolean | ANSI colors for output | | Console | pretty | boolean | Pretty-print JSON output | | Console | destination | string | stdout/stderr or custom stream | | File | path | string | Output file path | | File | mkdir | boolean | Create directories when missing | | File | rotation | boolean | object | File rotation options | | HTTP | url | string | Ingest endpoint | | HTTP | headers | Record<string, string> | Request headers | | HTTP | batchSize | number | Entries per batch | | HTTP | timeoutMs | number | Timeout in ms |

Examples

The examples folder is scaffolded but currently contains placeholders only. It will be populated alongside export wiring.

Production Best Practices

  1. Disable pretty printing in production:

    const logger = IgniterLogger.create()
        .addTransport({ target: "console", options: { pretty: false } })
        .build();
  2. Use file transport with rotation:

    const logger = IgniterLogger.create()
        .addTransport({
       	 target: "file",
       	 options: {
       		 path: "/var/log/app.log",
       		 mkdir: true,
       	 },
        })
        .build();
  3. Never log PII:

    // ❌ Bad
    logger.info("User logged in", { email, password });
    
    // ✅ Good
    logger.info("User logged in", { userId: user.id });
  4. Use child loggers for context:

    const requestLogger = logger.child("http", { requestId });

Troubleshooting

TRANSPORT_INVALID

Cause: Invalid transport target specified.
Solution: Use "console", "file", "http", or a valid Pino transport name.

LEVEL_INVALID

Cause: Invalid log level.
Solution: Use IgniterLogLevel values: fatal, error, warn, info, debug, trace.

File logs not appearing

Cause: Buffered writes not flushed.
Solution: Call await logger.flush() before process exit.

Note: Error codes above exist in the registry but are not thrown yet in v0.0.1. Validation will be added alongside export wiring.

Testing

pnpm test --filter @igniter-js/logger

Framework Integration

Next.js (API Route)

import { IgniterLogger } from "@igniter-js/logger";

const logger = IgniterLogger.create().withComponent("api").build();

export default function handler(req, res) {
	const requestLogger = logger.child("http", { requestId: req.headers["x-request-id"] });
	requestLogger.info("Incoming request", { method: req.method, path: req.url });
	res.status(200).json({ ok: true });
}

Express

import express from "express";
import { IgniterLogger } from "@igniter-js/logger";

const app = express();
const logger = IgniterLogger.create().withComponent("http").build();

app.get("/health", (req, res) => {
	logger.info("Health check", { requestId: req.header("x-request-id") });
	res.json({ ok: true });
});

Fastify

import Fastify from "fastify";
import { IgniterLogger } from "@igniter-js/logger";

const app = Fastify();
const logger = IgniterLogger.create().withComponent("http").build();

app.get("/health", async (request) => {
	logger.info("Health check", { requestId: request.headers["x-request-id"] });
	return { ok: true };
});

Documentation

License

MIT © Felipe Barcelos