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

@incubrain/logger

v0.3.5

Published

A modern, format-agnostic logging library for Node.js and browser environments, built on top of Consola with additional features for enterprise applications.

Readme

@incubrain/logger

A modern, format-agnostic logging library for Node.js and browser environments, built on top of Consola with additional features for enterprise applications.

Features

  • 🚀 Universal runtime support (Node.js and Browser)
  • 🎨 Beautiful console output powered by Consola
  • 🔄 Automatic log rotation with file transport
  • 🏷 Rich context and tag support
  • 📝 Structured logging
  • 🔍 Configurable debug levels
  • ⚡ Highly performant with buffered writes
  • 🔒 Type-safe API
  • 🌈 Format-agnostic - accepts any input style
  • 📁 Automatic error/warning logging in development mode
  • 🔎 Quick file logging for debugging purposes

Installation

# Using npm
npm install @incubrain/logger

# Using pnpm
pnpm add @incubrain/logger

# Using yarn
yarn add @incubrain/logger

Quick Start

import { logger } from "@incubrain/logger";

// Basic logging
logger.info("Application starting...");
logger.success("Database connected");
logger.error(new Error("Connection failed"));

// With context
const dbLogger = logger.withContext({
  service: "database",
  environment: "production",
});

dbLogger.info("Executing query");

// Advanced setup
import { setupLogger } from "@incubrain/logger";

const logger = await setupLogger({
  enableFileLogging: true,
  logFile: "app.log",
  setupErrorHandlers: true,
  context: {
    service: "api",
    version: "1.0.0",
  },
});

Format-Agnostic Logging

The logger accepts a wide variety of input formats, making it highly flexible for different coding styles:

// Console-style with template literals
const file = "user-component.vue";
logger.error(`Error loading component from ${file}`, error);

// With error objects in any position
logger.error(new Error("Authentication failed"));
logger.error("Operation failed", new Error("Database error"));
logger.error("Multiple issues", error1, error2);

// With additional context data
logger.info("Processing request", { userId: "user-123", requestId: "req-456" });
logger.error("API error", error, { statusCode: 500, endpoint: "/api/users" });

// Multiple additional arguments
logger.debug(
  "Component rendering",
  { name: "Button" },
  { renderTime: "5ms" },
  stats
);

// Object with message property
logger.info({ message: "User logged in", userId: "user-123", source: "web" });

// Just data (creates generic message)
logger.info({ userId: "user-123", action: "login", timestamp: new Date() });

All these approaches work seamlessly, with the logger intelligently handling each case.

File Logging

Enable file logging with automatic rotation:

import { setupLogger } from "@incubrain/logger";

const logger = await setupLogger({
  fileLogging: {
    enabled: true,
    filePath: "app", // Will create logs/app.0.log
    maxFileSize: 10 * 1024 * 1024, // 10MB
    maxFiles: 5,
    format: "json",
  },

  // Explicitly configure error logging (optional in dev mode)
  errorLogging: {
    enabled: true, // Already true by default in dev mode
    filePath: "error", // Will create logs/error.0.log
    level: 1, // Capture WARN level and below (ERROR, FATAL)
  },
});

Automatic Error Logging in Development

In development mode, all errors and warnings are automatically logged to a dedicated file for easier debugging:

// In development mode, this automatically logs errors to logs/error.0.log
import { setupLogger } from "@incubrain/logger";

await setupLogger(); // No additional config needed in dev mode!

// This error will be logged to both console and error.0.log
logger.error("Something went wrong", new Error("Database connection failed"));

Quick File Debugging

Need to quickly log specific data to a file? Use the logToFile utility:

import { logToFile } from "@incubrain/logger";

// Log complex data to a specific file for debugging
async function debugAuthFlow() {
  const userData = await getUserInfo();
  const tokenData = await getTokenInfo();

  // Will be saved to logs/auth-debug.0.log
  await logToFile(
    "auth-debug",
    {
      user: userData,
      token: tokenData,
      timestamp: new Date(),
    },
    {
      pretty: true, // Make it human-readable
    }
  );
}

Log Levels

import { LOG_LEVELS } from "@incubrain/logger";

// Available levels
logger.fatal("Critical error"); // 0
logger.error("Error occurred"); // 0
logger.warn("Warning message"); // 1
logger.log("Standard log"); // 2
logger.info("Info message"); // 3
logger.success("Operation completed"); // 3
logger.debug("Debug info"); // 4
logger.trace("Trace message"); // 5

// Set log level
logger.setLevel(LOG_LEVELS.DEBUG);

Proper Cleanup

To ensure all file streams are properly closed and there are no memory leaks:

import { cleanupLoggers } from "@incubrain/logger";

// Register shutdown handlers
process.on("SIGTERM", async () => {
  logger.info("Application shutting down");
  await cleanupLoggers();
  process.exit(0);
});

// Or manually clean up when needed
async function shutdown() {
  await cleanupLoggers();
}

Environment Variables

The logger respects the following environment variables:

  • LOG_LEVEL: Set the logging level
  • NODE_ENV: Determines default formatting options

Runtime Detection

The logger automatically detects the runtime environment and adjusts its behavior:

import { getRuntimeContext } from "@incubrain/logger";

const context = getRuntimeContext();
if (context.isFileSystemAvailable) {
  // Safe to use file logging
}

Best Practices

  1. Use Contexts for Related Logs
// Instead of repeating user context in every log
logger.info("User logged in", { userId: "123" });
logger.info("Loading dashboard", { userId: "123" });

// Create a contextual logger once
const userLogger = logger.withContext({ userId: "123" });
userLogger.info("User logged in");
userLogger.info("Loading dashboard");
  1. Structured Logging with Context
// Console-style provides both readability and structured data
logger.info(`Processing order ${orderId}`, {
  customer: customerId,
  items: itemCount,
  total: orderTotal,
});
  1. Error Handling Patterns
try {
  await apiCall();
} catch (error) {
  // Simple error logging
  logger.error(`API call failed for ${endpoint}`, error);

  // With additional context
  logger.error(`API call failed for ${endpoint}`, error, {
    requestId,
    statusCode: error.statusCode || 500,
    retryCount,
  });
}
  1. File Logging for Critical Operations
// For important operations, consider dedicated file logs
import { createFileLogger } from "@incubrain/logger";

const paymentLogger = createFileLogger("payment-transactions", {
  maxFiles: 30, // Keep longer history
  format: "jsonsl", // Compact one-line JSON for easier parsing
});

async function processPayment(paymentData) {
  try {
    const result = await paymentGateway.charge(paymentData);

    // Log successful transaction
    await paymentLogger.info({
      status: "success",
      transactionId: result.id,
      amount: paymentData.amount,
      customer: paymentData.customerId,
    });

    return result;
  } catch (error) {
    // Log failed transaction
    await paymentLogger.error({
      status: "failed",
      error: {
        message: error.message,
        code: error.code,
      },
      paymentData,
    });

    throw error;
  }
}

TypeScript Support

The library is written in TypeScript and provides full type definitions:

import type {
  LoggerInstance,
  LogLevel,
  LogContext,
  FileLoggerOptions,
} from "@incubrain/logger";

const context: LogContext = {
  serviceName: "auth-service",
  environment: "production",
  requestId: "req-123",
};

const fileOptions: FileLoggerOptions = {
  maxFileSize: 10 * 1024 * 1024,
  format: "json",
  pretty: false,
};

Architecture

@incubrain/logger/
├── core/        # Core logging functionality
├── runtime/     # Runtime detection and adaptation
├── transport/   # File transport and rotation
└── types/       # TypeScript definitions

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

License

MIT

Credits

Built with Consola