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

loggerect

v1.1.3

Published

A powerful, highly configurable logger for React and Node.js with TypeScript decorators, environment-aware logging, and source path tracking

Readme

✨ Features

  • 🎯 Accurate Source Tracking - See exact file:line in browser console (via build plugins)
  • 🎨 Beautiful Console Output - Styled badges, timestamps, and structured formatting
  • 🌈 Unified Colors - Server console colors match browser console (ANSI + CSS)
  • ⚛️ React Support - Hooks, HOCs, and decorators for React (optional)
  • 🖥️ Node.js Compatible - Works in pure Node.js without React
  • 🔧 Highly Configurable - Customize everything from log levels to badge styles
  • 🌍 Environment-Aware - Different behavior for development vs production
  • 📦 Zero Dependencies - Lightweight and fast
  • 🖥️ SSR Compatible - Works seamlessly with Next.js, Remix, and other SSR frameworks
  • 🧹 Smart Filtering - Automatically filters internal React/Node.js function names
  • 🔌 Universal Plugin Support - Works with Vite, Webpack, Turbopack, Rollup, and esbuild

📦 Installation

npm install loggerect

🚀 Quick Start

Basic Usage (Node.js & React)

import { logger, configure } from "loggerect";

// Configure (optional - has sensible defaults)
configure({
  level: "debug",
  timestamps: true,
});

// Log messages
logger.trace("Detailed trace information");
logger.debug("Debug information");
logger.info("General information");
logger.warn("Warning message");
logger.error("Error occurred", { details: "error info" });

Node.js Usage

// Pure Node.js - no React needed!
const { logger } = require("loggerect");
// or
import { logger } from "loggerect";

// Use in any Node.js application
logger.info("Server started", { port: 3000 });
logger.debug("Processing request", { method: "GET", path: "/api/users" });

// Component-scoped logging (works in Node.js too!)
const apiLogger = logger.forComponent("API").withTags("http", "rest");
apiLogger.info("Request received", { userId: 123 });

// Performance timing
logger.time("databaseQuery");
await queryDatabase();
logger.timeEnd("databaseQuery"); // Logs: ⏱️ databaseQuery: 45.23ms

React Hooks

import { useLogger, useLifecycleLogger } from "loggerect";

function MyComponent() {
  const log = useLogger("MyComponent");
  useLifecycleLogger("MyComponent"); // Auto-logs mount/unmount

  const handleClick = () => {
    log.info("Button clicked!");
  };

  return <button onClick={handleClick}>Click me</button>;
}

🔌 Source Tracking Setup

For accurate source file:line tracking in the browser console, add one of the build plugins:

Vite

// vite.config.ts
import { defineConfig } from "vite";
import logrectPlugin from "loggerect/vite-plugin";

export default defineConfig({
  plugins: [logrectPlugin()],
});

Next.js (Turbopack)

// next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  turbopack: {
    rules: {
      "*.{ts,tsx,js,jsx}": {
        loaders: ["loggerect/loader"],
      },
    },
  },
};

export default nextConfig;

Next.js (Webpack)

// next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  webpack: (config, { dev }) => {
    if (dev) {
      const logrectPlugin = require("loggerect/unplugin");
      config.plugins.push(logrectPlugin.webpack());
    }
    return config;
  },
};

export default nextConfig;

Webpack

// webpack.config.js
const logrectPlugin = require("loggerect/unplugin");

module.exports = {
  plugins: [logrectPlugin.webpack()],
};

Rollup

// rollup.config.js
import logrectPlugin from "loggerect/unplugin";

export default {
  plugins: [logrectPlugin.rollup()],
};

esbuild

// esbuild.config.js
const logrectPlugin = require("loggerect/unplugin");

require("esbuild").build({
  plugins: [logrectPlugin.esbuild()],
});

Babel (Alternative)

// babel.config.js
module.exports = {
  plugins: ["loggerect/babel-plugin"],
};

📚 API Reference

Core Logger (Node.js & React)

import { logger } from 'loggerect';

// Log levels
logger.trace(message, data?);  // 🔍 Most verbose
logger.debug(message, data?);  // 🐛 Debug info
logger.info(message, data?);   // ℹ️ General info
logger.warn(message, data?);   // ⚠️ Warnings
logger.error(message, data?);  // ❌ Errors

// Component-scoped logger
const componentLogger = logger.forComponent('MyComponent');
componentLogger.info('Scoped to MyComponent');

// With tags and metadata
const taggedLogger = logger
  .forComponent('MyComponent')
  .withTags('auth', 'api')
  .withMetadata({ userId: 123 });

// Performance timing
logger.time('fetchData');
await fetchData();
logger.timeEnd('fetchData'); // Logs: ⏱️ fetchData: 156.78ms

// Lifecycle helpers
logger.mount('ComponentName');    // 🚀 Mounted
logger.unmount('ComponentName');  // 💤 Unmounted
logger.render('ComponentName', 1, 2.5); // 🎨 Render #1 (2.5ms)

React Hooks

useLogger(componentName, options?)

Creates a component-scoped logger instance.

function MyComponent() {
  const log = useLogger("MyComponent");

  useEffect(() => {
    log.info("Component ready");
    log.debug("Fetching data...", { endpoint: "/api/users" });
  }, []);

  return <div>Hello</div>;
}

useLifecycleLogger(componentName, options?)

Automatically logs component mount and unmount events.

function MyComponent() {
  useLifecycleLogger("MyComponent");
  // Logs: 🚀 Mounted (on mount)
  // Logs: 💤 Unmounted (lifetime: 5234.12ms) (on unmount)

  return <div>Hello</div>;
}

useRenderLogger(componentName, options?)

Tracks and logs every render with timing.

function MyComponent() {
  useRenderLogger("MyComponent");
  // Logs: 🎨 Render #1 (2.34ms)
  // Logs: 🎨 Render #2 (1.12ms)

  return <div>Hello</div>;
}

useStateLogger<T>(componentName, stateName, initialValue, options?)

useState replacement that logs state changes.

function Counter() {
  const [count, setCount] = useStateLogger("Counter", "count", 0);
  // Logs: 🗃️ State "count" changed { prev: 0, next: 1 }

  return <button onClick={() => setCount((c) => c + 1)}>{count}</button>;
}

usePropChangeLogger<T>(componentName, props, options?)

Logs whenever props change with diff information.

function UserProfile({ user, theme }) {
  usePropChangeLogger("UserProfile", { user, theme });
  // Logs: 📦 Props changed { user: { prev: {...}, next: {...} } }

  return <div>{user.name}</div>;
}

useEffectLogger(componentName, effectName, effect, deps, options?)

useEffect replacement that logs effect execution.

function DataFetcher({ userId }) {
  useEffectLogger(
    "DataFetcher",
    "fetchUser",
    () => {
      fetchUser(userId);
    },
    [userId]
  );
  // Logs: ▶️ Effect "fetchUser" running
  // Logs: ⏹️ Effect "fetchUser" cleanup

  return <div>...</div>;
}

useCallbackLogger<T>(componentName, callbackName, callback, deps, options?)

useCallback replacement that logs callback executions.

function Form() {
  const handleSubmit = useCallbackLogger(
    "Form",
    "handleSubmit",
    (data) => {
      submitForm(data);
    },
    []
  );
  // Logs: 📞 Callback "handleSubmit" called (2.34ms)

  return <form onSubmit={handleSubmit}>...</form>;
}

useMemoLogger<T>(componentName, memoName, factory, deps, options?)

useMemo replacement that logs when values are recomputed.

function ExpensiveList({ items }) {
  const sortedItems = useMemoLogger(
    "ExpensiveList",
    "sortedItems",
    () => {
      return items.sort((a, b) => a.name.localeCompare(b.name));
    },
    [items]
  );
  // Logs: 🧮 Memo "sortedItems" computed (5.67ms)

  return (
    <ul>
      {sortedItems.map((item) => (
        <li>{item.name}</li>
      ))}
    </ul>
  );
}

useTimer(componentName, options?)

Manual performance timing within components.

function DataLoader() {
  const timer = useTimer("DataLoader");

  const loadData = async () => {
    timer.start("loadData");
    const data = await fetchData();
    timer.end("loadData"); // Logs: ⏱️ loadData: 234.56ms
    return data;
  };

  return <button onClick={loadData}>Load</button>;
}

useWhyDidYouRender<T>(componentName, props, options?)

Debug tool to understand why a component re-rendered.

function MyComponent(props) {
  useWhyDidYouRender("MyComponent", props);
  // Logs detailed information about what caused the re-render

  return <div>...</div>;
}

Higher-Order Component (HOC)

import { withLogger } from "loggerect";

const MyComponent = ({ name }) => <div>Hello {name}</div>;

// Basic usage
export default withLogger(MyComponent);

// With options
export default withLogger(MyComponent, {
  trackRenders: true,
  trackPropChanges: true,
  logLifecycle: true,
  displayName: "MyAwesomeComponent",
  level: "debug",
  tags: ["ui", "feature"],
});

TypeScript Decorators

Note: Requires experimentalDecorators: true in tsconfig.json

import { Log, LogClass, Trace, Debug, Info, Warn, Error } from "loggerect";

class UserService {
  @Log()
  async fetchUser(id: string) {
    // Logs: → fetchUser() { args: ["123"] }
    // Logs: ← fetchUser() (156.78ms)
    return await api.getUser(id);
  }

  @Log({ logArgs: false, logTime: true })
  processData(data: any) {
    // Custom options
  }

  @Debug()
  debugMethod() {
    /* ... */
  }

  @Info()
  infoMethod() {
    /* ... */
  }

  @Warn()
  warnMethod() {
    /* ... */
  }

  @Error()
  errorMethod() {
    /* ... */
  }
}

// Log entire class
@LogClass()
class MyService {
  // All methods will be logged
}

🎨 Log Levels & Badge Colors

loggerect uses styled badges with consistent colors for each log level:

Visual demonstration:

| Level | Badge | Background Color | Text Color | Description | | --------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | ---------- | ------------------------------ | | TRACE | 🔍 TRACE | rgba(107, 114, 128, 0.2) (Gray) | #9CA3AF | Most verbose, detailed tracing | | DEBUG | 🐛 DEBUG | rgba(34, 197, 94, 0.2) (Green) | #22c55e | Debug information | | INFO | ℹ️ INFO | rgba(59, 130, 246, 0.2) (Blue) | #3b82f6 | General information | | WARN | ⚠️ WARN | rgba(234, 179, 8, 0.2) (Yellow) | #eab308 | Warnings | | ERROR | ❌ ERROR | rgba(239, 68, 68, 0.2) (Red) | #ef4444 | Errors |

Additional Badges

| Badge | Usage | | ----- | ------------------ | | 🚀 | Component mount | | 💤 | Component unmount | | 🎨 | Component render | | 🔄 | Component update | | 📦 | Prop changes | | 🗃️ | State changes | | ⏱️ | Performance timing |

All badges use a semi-transparent background (20% opacity) with matching text colors for a modern, readable console appearance.

⚙️ Configuration

import { configure } from "loggerect";

configure({
  // Environment & Level
  environment: "development", // 'development' | 'production' | 'test'
  level: "debug", // 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent'

  // Formatting
  format: "pretty", // 'pretty' | 'json' | 'minimal' | 'detailed'
  timestamps: true,
  timestampFormat: "locale", // 'locale' | 'iso' | 'unix' | 'relative'
  colors: true,

  // Source Tracking
  includeSourcePath: "auto", // true | false | 'auto'
  includeStackTrace: true,

  // React-specific
  trackRenders: true,
  trackPropChanges: true,
  trackStateChanges: true,

  // Performance
  performance: true,

  // Output Control
  groupLogs: true,
  collapseGroups: true,
  maxDepth: 4,
  maxArrayLength: 100,
  maxStringLength: 1000,

  // Persistence (experimental)
  persist: false,
  storageKey: "loggerect_logs",
  maxPersistedLogs: 1000,

  // Custom Styles (defaults shown below)
  styles: {
    // TRACE: Gray background (rgba(107, 114, 128, 0.2)), Gray text (#9CA3AF)
    trace:
      "background: rgba(107, 114, 128, 0.2); color: #9CA3AF; padding: 2px 8px; border-radius: 4px; font-weight: 600;",
    // DEBUG: Green background (rgba(34, 197, 94, 0.2)), Green text (#22c55e)
    debug:
      "background: rgba(34, 197, 94, 0.2); color: #22c55e; padding: 2px 8px; border-radius: 4px; font-weight: 600;",
    // INFO: Blue background (rgba(59, 130, 246, 0.2)), Blue text (#3b82f6)
    info: "background: rgba(59, 130, 246, 0.2); color: #3b82f6; padding: 2px 8px; border-radius: 4px; font-weight: 600;",
    // WARN: Yellow background (rgba(234, 179, 8, 0.2)), Yellow text (#eab308)
    warn: "background: rgba(234, 179, 8, 0.2); color: #eab308; padding: 2px 8px; border-radius: 4px; font-weight: 600;",
    // ERROR: Red background (rgba(239, 68, 68, 0.2)), Red text (#ef4444)
    error:
      "background: rgba(239, 68, 68, 0.2); color: #ef4444; padding: 2px 8px; border-radius: 4px; font-weight: 600;",
  },

  // Custom Badges
  badges: {
    trace: "🔍",
    debug: "🐛",
    info: "ℹ️",
    warn: "⚠️",
    error: "❌",
    render: "🎨",
    mount: "🚀",
    unmount: "💤",
    props: "📦",
    state: "🗃️",
    time: "⏱️",
  },
});

Environment-Specific Configuration

configure({
  // Auto-detected, or set manually
  environment: process.env.NODE_ENV,

  // Different levels per environment
  level: process.env.NODE_ENV === "production" ? "warn" : "trace",

  // Disable source paths in production
  includeSourcePath: process.env.NODE_ENV !== "production",

  // Minimal format in production
  format: process.env.NODE_ENV === "production" ? "minimal" : "pretty",
});

📤 Entry Points

loggerect provides multiple entry points for different use cases:

// Main entry - SSR-safe (no React dependencies)
// Use in server components, API routes, and utility functions
import { logger, configure, isServer, isClient } from "loggerect";

// React hooks (client components only)
import { useLogger, useLifecycleLogger, useStateLogger } from "loggerect/hooks";

// React HOCs (client components only)
import { withLogger, withLoggerRef } from "loggerect/react";

// Core only (alternative SSR entry point)
import { logger, configure } from "loggerect/core";

When to Use Which Entry Point

  • loggerect (main): Use in server components, API routes, and any SSR context
  • loggerect/hooks: Use in client components that need React hooks
  • loggerect/react: Use in client components that need HOCs
  • loggerect/core: Alternative SSR entry point (same as main)

🌐 SSR Support

loggerect is fully SSR-compatible with separate entry points for server and client code. The main loggerect package is SSR-safe and can be used directly in server components:

// Next.js Server Component (SSR-safe)
import { logger, isServer } from "loggerect";

export default async function Page() {
  if (isServer()) {
    const log = logger
      .forComponent("Page")
      .withTags("server", "page");
    
    log.info("Rendering page on server");
  }

  return <div>Hello World</div>;
}

Entry Points for SSR

// Main entry - SSR-safe (no React dependencies)
import { logger, configure, isServer, isClient } from "loggerect";

// React hooks (client components only)
import { useLogger, useLifecycleLogger } from "loggerect/hooks";

// React HOCs (client components only)
import { withLogger } from "loggerect/react";

Server Console Colors

loggerect automatically matches console colors between server and browser:

  • Server console: Uses ANSI color codes (RGB) matching CSS colors exactly
  • Browser console: Uses CSS styling with matching colors
  • Badge styling: Same background and text colors on both server and client
  • Component names: Automatically extracted and filtered from stack traces
  • Smart filtering: Filters out internal React/Node.js function names and minified code

The server console output will look identical to the browser console, with matching badge colors and spacing.

📋 Console Output Examples

Pretty Format (Development)

The console output uses styled badges with colors matching each log level. Colors are consistent between server and browser consoles. Here's what they look like:

Example log entries with colored badges:

Badge colors reference:

  • 🔍 TRACE - Gray badge (rgba(107, 114, 128, 0.2) bg, #9CA3AF text)
  • 🐛 DEBUG - Green badge (rgba(34, 197, 94, 0.2) bg, #22c55e text)
  • ℹ️ INFO - Blue badge (rgba(59, 130, 246, 0.2) bg, #3b82f6 text)
  • ⚠️ WARN - Yellow badge (rgba(234, 179, 8, 0.2) bg, #eab308 text)
  • ❌ ERROR - Red badge (rgba(239, 68, 68, 0.2) bg, #ef4444 text)

JSON Format (Production/Logging Services)

{
  "timestamp": "2024-01-15T04:25:51.000Z",
  "level": "info",
  "component": "Navbar",
  "message": "🚀 Mounted"
}

Minimal Format

[INFO] Navbar: 🚀 Mounted

🔧 TypeScript Support

loggerect is written in TypeScript and provides full type definitions:

import type {
  LogLevel,
  LogrectConfig,
  HOCOptions,
  DecoratorOptions,
} from "loggerect";

// All hooks and functions are fully typed
const log = useLogger<{ userId: string }>("MyComponent", {
  metadata: { userId: "123" },
});

📝 License

MIT © loggerect