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

@deepracticex/logger

v1.1.1

Published

Unified logging system for Deepractice projects using Pino

Readme

@deepracticex/logger

Universal logging system for all JavaScript runtimes - Node.js, Cloudflare Workers, Browser, and more.

Features

  • 🌍 Universal - Works in Node.js, Cloudflare Workers, Browser, and other JavaScript runtimes
  • 🎯 Platform-Specific Optimizations - Pino for Node.js, lightweight console for edge/browser
  • 📦 Tree-Shakeable - Only bundles the code you need for your platform
  • 🎨 Pretty Console Output - Color support with automatic MCP stdio detection
  • 📁 File Logging - Daily rotation for Node.js (when enabled)
  • 📍 Caller Location Tracking - Automatic file/line tracking
  • 🔧 TypeScript Support - Full type safety
  • Zero Config - Sensible defaults, customizable when needed

Installation

pnpm add @deepracticex/logger

Platform-Specific Entry Points

Choose the right entry point for your platform:

Node.js (Default)

// Uses Pino for high performance logging
import { createLogger } from "@deepracticex/logger";
// or explicitly
import { createLogger } from "@deepracticex/logger/nodejs";

const logger = createLogger({
  level: "info",
  name: "my-service",
  console: true,
  file: true, // File logging with daily rotation
});

logger.info("Server started");

Cloudflare Workers

// Uses lightweight console adapter (no Node.js dependencies)
import { createLogger } from "@deepracticex/logger/cloudflare-workers";

const logger = createLogger({
  level: "info",
  name: "my-worker",
  console: true,
});

logger.info("Request handled");

Browser

// Uses browser-optimized console adapter
import { createLogger } from "@deepracticex/logger/browser";

const logger = createLogger({
  level: "debug",
  name: "my-app",
  console: true,
  colors: true,
});

logger.info("App initialized");

Test Environment (Vitest/Jest)

// Uses in-memory test adapter with log capture
import {
  createLogger,
  getTestLogs,
  clearTestLogs,
} from "@deepracticex/logger/test";

const logger = createLogger({
  level: "debug",
  name: "my-service",
  console: false, // Silent by default in tests
});

// Your test code
logger.info("test message");

// Assert logs were captured
const logs = getTestLogs();
expect(logs).toHaveLength(1);
expect(logs[0].message).toBe("test message");

// Clean up between tests
clearTestLogs();

Quick Start

Default Logger (Node.js)

import { info, warn, error, debug } from "@deepracticex/logger";

info("Server started");
warn("Low memory");
error("Connection failed");
debug("Debug info");

Custom Logger

import { createLogger } from "@deepracticex/logger";

const logger = createLogger({
  level: "debug",
  name: "@deepracticex/my-service",
  console: true,
  file: {
    dirname: "/var/log/myapp",
  },
  colors: true,
});

logger.info("Custom logger initialized");

Configuration

LoggerConfig

interface LoggerConfig {
  // Log level (default: 'info')
  level?: "fatal" | "error" | "warn" | "info" | "debug" | "trace";

  // Package/service name (default: 'app')
  name?: string;

  // Console output (default: true)
  console?: boolean;

  // File logging - Node.js only (default: false)
  file?:
    | boolean
    | {
        dirname?: string; // Log directory (default: ~/.deepractice/logs)
      };

  // Color support (default: true, auto-disabled in MCP stdio)
  colors?: boolean;
}

Environment Variables

  • LOG_LEVEL - Set log level (default: 'info')
  • MCP_TRANSPORT=stdio - Auto-disable colors for MCP stdio mode
  • DEEPRACTICE_NO_WORKERS=true - Force sync mode (useful for Electron)

Log Levels

  • fatal - Critical errors that require immediate attention
  • error - Errors that need to be fixed
  • warn - Warnings about potential issues
  • info - General information (default)
  • debug - Detailed debug information
  • trace - Very verbose trace information

Platform Details

Node.js

Uses Pino for high-performance logging:

  • File logging with daily rotation
  • Automatic caller location tracking
  • Worker threads for better performance
  • MCP stdio mode detection

File Structure:

~/.deepractice/logs/
├── deepractice-2025-10-13.log       # All logs
└── deepractice-error-2025-10-13.log # Error logs only

Cloudflare Workers

Uses lightweight console adapter:

  • Minimal bundle size (~1.5KB)
  • No Node.js dependencies
  • Full logging API compatibility
  • Works with Wrangler dev and production

Browser

Uses browser-optimized console adapter:

  • Native console API
  • Color support
  • Source map integration
  • DevTools friendly

Test Environment

Uses in-memory test adapter:

  • Auto-detected in vitest/jest (via VITEST=true or NODE_ENV=test)
  • Silent by default (no console output)
  • Captures all logs in memory for assertions
  • Zero I/O overhead for fast tests
  • Utilities: getTestLogs(), clearTestLogs(), getTestLogsByLevel()

Usage in tests:

import {
  createLogger,
  getTestLogs,
  clearTestLogs,
} from "@deepracticex/logger/test";

describe("my feature", () => {
  const logger = createLogger();

  afterEach(() => {
    clearTestLogs(); // Clean up between tests
  });

  it("should log messages", () => {
    logger.info("test started");
    logger.warn("warning message");

    const logs = getTestLogs();
    expect(logs).toHaveLength(2);
    expect(logs[0].level).toBe("info");
  });
});

Auto-detection:

When running in vitest, the default @deepracticex/logger import automatically uses the test adapter:

// Automatically uses test adapter in vitest
import { createLogger } from "@deepracticex/logger";

const logger = createLogger(); // No console output in tests

Enable console output for debugging:

// Show logs in test output
const logger = createLogger({ console: true });

// Or run with verbose reporter
// pnpm test -- --reporter=verbose

Examples

Node.js Service

import { createLogger } from "@deepracticex/logger";

const logger = createLogger({
  level: process.env.LOG_LEVEL || "info",
  name: "@deepracticex/api-server",
  console: true,
  file: {
    dirname: "./logs",
  },
});

logger.info({ port: 3000 }, "Server started");
logger.error({ err: error }, "Database connection failed");

Cloudflare Worker

import { createLogger } from "@deepracticex/logger/cloudflare-workers";

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const logger = createLogger({
      name: "my-worker",
      level: env.LOG_LEVEL || "info",
    });

    logger.info({ url: request.url }, "Request received");

    try {
      // Handle request
      return new Response("OK");
    } catch (error) {
      logger.error({ error }, "Request failed");
      return new Response("Error", { status: 500 });
    }
  },
};

Browser App

import { createLogger } from "@deepracticex/logger/browser";

const logger = createLogger({
  name: "my-app",
  level: "debug",
  colors: true,
});

logger.info("App initialized");

document.addEventListener("click", (e) => {
  logger.debug({ target: e.target }, "User clicked");
});

Architecture

The logger uses a multi-adapter architecture with automatic runtime detection:

  1. Pino Adapter - For Node.js (high performance, file support)
  2. Console Adapter - For edge/browser (lightweight, universal)
  3. Test Adapter - For test environments (in-memory, inspectable)

Platform-specific entry points ensure only the necessary adapter is bundled:

@deepracticex/logger          → Auto-detect → appropriate adapter
@deepracticex/logger/nodejs   → nodejs.ts → pino-adapter
@deepracticex/logger/cloudflare-workers → cloudflare-workers.ts → console-adapter
@deepracticex/logger/browser  → browser.ts → console-adapter
@deepracticex/logger/test     → test.ts → test-adapter

Auto-detection priority:

  1. Test environment (VITEST=true or NODE_ENV=test) → test adapter
  2. Cloudflare Workers (caches API present) → console adapter
  3. Node.js (process.versions.node) → pino adapter
  4. Fallback → console adapter (browser)

Bundle Size

  • Node.js: Full pino functionality (~200KB with dependencies)
  • Cloudflare Workers: ~1.5KB (console adapter only)
  • Browser: ~1.5KB (console adapter only)
  • Test: ~2KB (test adapter with inspection utilities)

FAQ

Why platform-specific entry points?

This allows bundlers (esbuild, webpack, etc.) to tree-shake unused code. If you use the Cloudflare Workers entry, the 200KB+ pino dependency won't be included in your bundle.

Can I use the same logger across different files?

Yes! Create a logger module:

// src/infrastructure/logger/index.ts
import { createLogger } from "@deepracticex/logger/cloudflare-workers";

export const logger = createLogger({
  name: "my-app",
  level: "info",
});

Then import everywhere:

import { logger } from "~/infrastructure/logger";

logger.info("Hello from any file!");

Does it work with monorepos?

Yes! Each package can use the appropriate entry point:

// apps/api (Node.js)
import { createLogger } from "@deepracticex/logger";

// apps/worker (Cloudflare)
import { createLogger } from "@deepracticex/logger/cloudflare-workers";

// apps/web (Browser)
import { createLogger } from "@deepracticex/logger/browser";

How do I use it in tests?

The logger automatically detects test environments (vitest/jest) and uses the test adapter:

// Automatically silent in tests
import { createLogger } from "@deepracticex/logger";
const logger = createLogger();

logger.info("message"); // Captured, but no console output

To inspect logs in tests:

import {
  createLogger,
  getTestLogs,
  clearTestLogs,
} from "@deepracticex/logger/test";

const logger = createLogger();
logger.info("test message");

const logs = getTestLogs();
expect(logs[0].message).toBe("test message");

clearTestLogs(); // Clean up

How do I see logs when debugging tests?

Use vitest's verbose reporter:

pnpm test -- --reporter=verbose

Or enable console output explicitly:

const logger = createLogger({ console: true });

License

MIT