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 🙏

© 2025 – Pkg Stats / Ryan Hefner

i45-jslogger

v2.0.1

Published

A simple JavaScript logger for capturing events in the console and local storage.

Readme

NodeJS package

A browser based logger to track events during development and testing. Log entries are written to the console as well as stored in localStorage.

⚠️ v2.0.0 Breaking Changes

  • Event Namespacing: CustomEvents now use i45-logger: prefix
    • Old: window.addEventListener("LOG", ...)
    • New: window.addEventListener("i45-logger:LOG", ...)
  • Property Names: Better, clearer names
    • enableEventsenableDispatchEvents (clearer what it controls)
    • enableLoggingloggingEnabled (better grammar)
  • Removed Exports: iLogger and iLoggerValidator are no longer exported
  • Removed Deprecated: clearEvents() method removed (use clearEventLog(), clearConsole(), or clearAll())
  • Return Types: addClient() and removeClient() return boolean instead of 0|1

See CHANGES.md for full migration guide.

Environment Support

  • Browser: Full support with all features
  • ⚠️ Node.js: Limited support (no localStorage, no events)
  • ⚠️ SSR (Next.js, Nuxt): Requires client-side initialization

The package now includes environment detection and won't crash in Node.js environments, but localStorage and CustomEvent features will be unavailable.

Contents

Installation

npm i i45-jslogger

Quick Start

Simple Usage (Default Instance)

import logger from "i45-jslogger";

logger.log("Basic log message");
logger.info("This is an info message");
logger.warn("This is a warning");
logger.error("This is an error");

Multiple Instances

import { Logger } from "i45-jslogger";

// Separate loggers for different purposes
const debugLogger = new Logger();
const analyticsLogger = new Logger();

debugLogger.info("Debug information");
analyticsLogger.suppressConsole = true; // Only log to localStorage and clients

Console output: Console output

localStorage output: Local storage

API Overview

Logging Methods

All methods support method chaining and return this.

logger.log("message", ...args); // Basic log
logger.info("message", ...args); // Info level
logger.warn("message", ...args); // Warning level
logger.error("message", ...args); // Error level

Client Management

logger.addClient(customLogger); // Returns: boolean
logger.removeClient(customLogger); // Returns: boolean
logger.clients(); // Returns: Array
logger.removeAllClients(); // Returns: this

Event Management

logger.getEvents(); // Returns: Array of logged events
logger.clearEventLog(); // Clear localStorage events
logger.clearConsole(); // Clear browser console
logger.clearAll(); // Clear both

Full API documentation available in TypeScript definitions.

Configuration

Properties

// Enable/disable logging
logger.loggingEnabled = true; // Default: true

// CustomEvent dispatching to window
logger.enableDispatchEvents = true; // Default: true

// Suppress outputs
logger.suppressNative = false; // Skip localStorage/events (Default: false)
logger.suppressConsole = false; // Skip console output (Default: false)

// Storage limits
logger.maxEvents = null; // Default: null (unlimited)
// Set to positive integer to limit stored events (oldest are removed)
// Set to 0 to prevent event storage entirely

Console Filtering

Filter by log levels in the browser console:

Logging levels

Custom Logger Clients

Add custom clients to pipe logs to APIs, files, or analytics services.

Client Interface

const customLogger = {
  log: (message, ...args) => {
    /* custom logic */
  },
  info: (message, ...args) => {
    /* custom logic */
  },
  warn: (message, ...args) => {
    /* custom logic */
  },
  error: (message, ...args) => {
    /* custom logic */
  },
};

logger.addClient(customLogger); // Returns true if added successfully

Example: API Logger

const apiLogger = {
  log: (msg, ...args) =>
    fetch("/api/logs", {
      method: "POST",
      body: JSON.stringify({ level: "log", msg, args }),
    }),
  info: (msg, ...args) =>
    fetch("/api/logs", {
      method: "POST",
      body: JSON.stringify({ level: "info", msg, args }),
    }),
  warn: (msg, ...args) =>
    fetch("/api/logs", {
      method: "POST",
      body: JSON.stringify({ level: "warn", msg, args }),
    }),
  error: (msg, ...args) =>
    fetch("/api/logs", {
      method: "POST",
      body: JSON.stringify({ level: "error", msg, args }),
    }),
};

logger.addClient(apiLogger);
logger.info("User logged in", { userId: 123 }); // Logs to console AND API

Event Listeners

Subscribe to log events using window CustomEvents with namespaced event names.

Available Events

Events are namespaced with i45-logger: prefix to prevent conflicts:

window.addEventListener("i45-logger:LOG", (event) => {
  console.log(event.detail); // { message, args, timestamp }
});

window.addEventListener("i45-logger:INFO", (event) => {
  /* ... */
});
window.addEventListener("i45-logger:WARN", (event) => {
  /* ... */
});
window.addEventListener("i45-logger:ERROR", (event) => {
  /* ... */
});

Disable Events

logger.enableDispatchEvents = false; // Stop dispatching CustomEvents

Advanced Usage

Use in Classes

import logger from "i45-jslogger";

class DataService {
  #debug;

  constructor(debug = false) {
    this.#debug = debug;
  }

  fetchData() {
    if (this.#debug) logger.info("Fetching data...");

    // ... fetch logic

    if (this.#debug) logger.info("Data fetched successfully");
  }
}

Multiple Isolated Loggers

import { Logger } from "i45-jslogger";

// Development logger
const devLog = new Logger();
devLog.enableLogging = process.env.NODE_ENV === "development";

// Analytics logger (console suppressed)
const analyticsLog = new Logger();
analyticsLog.suppressConsole = true;
analyticsLog.addClient(analyticsClient);

// Error tracking logger
const errorLog = new Logger();
errorLog.suppressNative = true;
errorLog.addClient(sentryClient);

Testing with Isolated Instances

import { Logger } from "i45-jslogger";

test("logging disabled", () => {
  const logger = new Logger();
  logger.enableLogging = false;

  logger.info("test"); // Won't log
  expect(logger.getEvents()).toHaveLength(0);
});

TypeScript Support

Full TypeScript definitions included:

import logger, { Logger, LoggerClient, LogEvent } from "i45-jslogger";

const customClient: LoggerClient = {
  log: (msg) => console.log(msg),
  info: (msg) => console.info(msg),
  warn: (msg) => console.warn(msg),
  error: (msg) => console.error(msg),
};

const events: LogEvent[] = logger.getEvents();

Contributing

Contributions welcome! Please see CHANGES.md for the full changelog and migration guides.

Planning for v3.0.0 is underway - see the v3.0.0 roadmap for upcoming features.

License

MIT

Links