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

plslog

v1.2.0

Published

Custom log for browser

Downloads

246

Readme

plslog

A powerful, browser-first logging library with structured logging, namespaces, and environment-aware behavior.

Features

  • Log levels - Hierarchical levels (debug, info, warn, error) with configurable visibility.
  • Namespaces - Scoped loggers with pattern matching and filtering.
  • Structured logging - JSON-first with pretty-format for objects and arrays.
  • Deep nested objects - Configurable maxDepth for safe, readable traversal of nested data.
  • Pick / omit fields - Whitelist or blacklist fields (dot notation, wildcards); redact, hide, or show type/length.
  • Dedup & once - Collapse repeated identical logs; once() for one-time messages, flushDedup() to flush buffer.
  • Conditional logging - when() / unless() with booleans or predicates for conditional log execution.
  • Assert - assert(condition, message, ...args) logs error only when condition is falsy.
  • Truncate - Limit object fields, string length, and array items to keep output concise.
  • Transports - Forward structured log entries to external destinations (remote services, files, etc.).
  • Pretty console - Styled, readable output in development.
  • Environment-aware - Adjust behavior by environment (for example NODE_ENV).

Guide

Log Levels

plslog supports a hierarchical log level system with five levels:

  • debug - priority 0
  • info - priority 1
  • warn - priority 2
  • error - priority 3
  • none - priority 4

When a log level is set, only messages at that level or higher priority are logged.

import plslog from 'plslog';

plslog.configure({ level: 'warn' });

const logger = plslog('app');

logger.debug('This will not be logged');
logger.info('This will not be logged');
logger.warn('This will be logged');
logger.error('This will be logged');

You can also specify active levels explicitly:

plslog.configure({
  activeLevels: ['warn', 'error'],
});

Namespaces

Organize logs with namespaces and filter them globally.

const apiLogger = plslog('api');
const dbLogger = plslog('db');
const authLogger = plslog('auth');

apiLogger.info('API request received');
dbLogger.debug('Query executed');
authLogger.warn('Invalid token');
plslog.configure({ namespaces: 'api,db' });
plslog.configure({ namespaces: 'app:*' });
plslog.configure({ namespaces: '*,-app:db:*' });
plslog.configure({ namespaces: '*' });

Supported patterns:

  • * matches all namespaces
  • app:* matches namespaces starting with app:
  • app:api,app:db matches specific namespaces
  • -app:db:* excludes a matching namespace pattern

Truncate Large Data

Prevent runaway output from large objects, arrays, or strings.

const logger = plslog('api');

logger.truncate(5).debug('User', largeUser);
logger.truncate({ fields: 5, string: 80, array: 3 }).debug('Order', order);
plslog.configure({ truncate: { fields: 10, string: 200, array: 5 } });

const logger = plslog({ namespace: 'api', truncate: { fields: 5 } });

logger.truncate(3).debug('Compact view', bigObject);

Truncation indicators:

  • Fields: { a: 1, b: 2, '...': '+8 more fields' }
  • Array: [1, 2, 3, '... +7 more']
  • String: 'first 80 chars... [200 chars]'

Priority order: per-log truncate() > instance option > global config

Structured Logging

Objects and arrays are automatically serialized and formatted.

const logger = plslog('api');

logger.info('User data', {
  id: 123,
  name: 'John',
  email: '[email protected]',
});

logger.debug('Items', [1, 2, 3, { nested: 'value' }]);

logger.info('Complex data', {
  user: {
    profile: {
      settings: { theme: 'dark' },
    },
  },
});

Special handling includes:

  • Blob and File objects with metadata
  • base64 strings with preview and length information
  • deep nesting with configurable maxDepth
plslog.configure({ maxDepth: 5 });

const logger = plslog({ namespace: 'app', maxDepth: 10 });
logger.maxDepth(3).debug('Deep object', veryDeepObject);

Pretty Console Output

In development, plslog provides:

  • color-coded log levels
  • structured formatting for arrays and objects
  • namespace badges
  • browser console integration with matching console methods

Example:

[app] DEBUG
User data {
  id: 123,
  name: "John",
  email: "[email protected]"
}

Environment-Aware Behavior

import plslog from 'plslog';

const isProduction = import.meta.env.PROD;

const LOG_LEVELS_PROD = ['warn', 'error'];
const LOG_LEVELS_DEV = ['debug', 'info', 'warn', 'error'];

plslog.configure({
  activeLevels: isProduction ? LOG_LEVELS_PROD : LOG_LEVELS_DEV,
  namespaces: import.meta.env.VITE_LOG_NAMESPACES,
  maxDepth: isProduction ? 3 : 10,
});

Example environment variables:

# .env.development
VITE_LOG_NAMESPACES=*

# .env.production
VITE_LOG_NAMESPACES=app:api,app:db

Transports

Send structured log data to external destinations alongside normal console output.

plslog.configure({
  transports: [
    {
      write(entry) {
        fetch('/logs', {
          method: 'POST',
          body: JSON.stringify(entry),
        });
      },
    },
  ],
});

Filter transport delivery by level:

plslog.configure({
  transports: [
    {
      levels: ['warn', 'error'],
      write(entry) {
        sendToErrorTracker(entry);
      },
    },
  ],
});

Multiple transports:

plslog.configure({
  transports: [
    {
      levels: ['error'],
      write(entry) {
        errorTracker.capture(entry);
      },
    },
    {
      write(entry) {
        analyticsService.log(entry);
      },
    },
  ],
});

TransportEntry fields:

| Field | Type | Description | | --- | --- | --- | | namespace | string | Logger namespace | | level | LogLevel | Log level | | message | string | Log message | | args | unknown[] | Raw arguments | | timestamp | number | Unix timestamp in milliseconds |

Transport errors are swallowed to avoid crashing the app.

Installation

npm install plslog
# or
pnpm add plslog
# or
yarn add plslog

Quick Start

import plslog from 'plslog';

plslog.configure({
  level: 'debug',
  namespaces: '*',
});

const logger = plslog('my-app');

logger.debug('Debug message');
logger.info('Info message', { data: 'value' });
logger.warn('Warning message');
logger.error('Error message', new Error('Something went wrong'));

API Reference

plslog(options?: LoggerOptions | string): Logger

Creates a new logger instance.

Parameters:

  • options: a namespace string or a LoggerOptions object
  • namespace?: string - logger namespace, default 'app'
  • level?: LogLevel - instance log level
  • maxDepth?: number - maximum object serialization depth
  • truncate?: TruncateConfig - default truncation config for this instance

Returns a Logger instance.

plslog.configure(options: GlobalConfig): void

Configures global logging behavior.

Parameters:

  • namespaces?: string - comma-separated namespace filter
  • level?: LogLevel - global hierarchical log level
  • activeLevels?: LogLevel[] - explicit active levels
  • maxDepth?: number - global max serialization depth
  • truncate?: TruncateConfig - global truncation config
  • transports?: Transport[] - structured log transports

Logger methods

  • debug(message: string, ...args: unknown[]): Logger
  • info(message: string, ...args: unknown[]): Logger
  • warn(message: string, ...args: unknown[]): Logger
  • error(message: string, ...args: unknown[]): Logger
  • setLevel(level: LogLevel): void
  • maxDepth(maxDepth: number): Logger
  • truncate(config: number | TruncateConfig): Logger
  • pick(fields: string[]): Logger
  • omit(fields: FilterFieldConfig[]): Logger
  • when(condition: Condition): Logger
  • unless(condition: Condition): Logger
  • assert(condition: unknown, message: string, ...args: unknown[]): Logger
  • once(enabled?: boolean): Logger
  • flushDedup(): Logger

License

MIT