JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 69
  • Score
    100M100P100Q89417F
  • License MIT

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

Package Exports

  • loggerect
  • loggerect/babel-plugin
  • loggerect/core
  • loggerect/hooks
  • loggerect/loader
  • loggerect/react
  • loggerect/unplugin
  • loggerect/vite-plugin

Readme

loggerect

loggerect

A powerful, zero-dependency logger for React and Node.js with full source path tracking, TypeScript decorators, and environment-aware output. See exactly where your logs come from.

npm version License: MIT npm downloads bundle size

โœจ 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:

๐Ÿ” TRACE ๐Ÿ› DEBUG โ„น๏ธ INFO โš ๏ธ WARN โŒ ERROR
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:

[4:25:51 AM] โ„น๏ธ INFO | Navbar.useLifecycleLogger.useEffect() โ†’ ๐Ÿš€ Mounted @ src/components/Navbar.tsx:9

[4:25:51 AM] ๐Ÿ› DEBUG | Navbar.Navbar.useEffect() โ†’ Scroll listener attached @ src/components/Navbar.tsx:8
[4:25:51 AM] ๐Ÿ› DEBUG | ๐Ÿ“Š [Navbar].Navbar.useEffect() Data: @ src/components/Navbar.tsx:8
{ scrollY: 0 }

[4:25:52 AM] โš ๏ธ WARN | DataService.fetchData() โ†’ Rate limit approaching @ src/services/DataService.ts:45

[4:25:53 AM] โŒ ERROR | AuthService.login() โ†’ Authentication failed @ src/services/AuthService.ts:23

[4:25:50 AM] ๐Ÿ” TRACE | Component.render() โ†’ Rendering child components @ src/components/Component.tsx:15

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


See exactly where your logs come from.
Website ยท GitHub ยท npm