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

@onamfc/developer-log

v1.2.3

Published

A lightweight console.log wrapper that suppresses output in production

Readme

@onamfc/developer-log

A lightweight wrapper for all console methods that automatically suppresses output in production environments and supports optional tag-based filtering in development.

Installation

npm install @onamfc/developer-log

Usage

Import and use just like you would use the native console object:

import { dev } from '@onamfc/developer-log';

// Basic logging
dev.log('Hello, world!');
dev.error('An error occurred');
dev.warn('This is a warning');
dev.info('Informational message');
dev.debug('Debug information');

// Logging with tags for filtering (optional)
dev.log('Database connected', { tag: 'database' });
dev.error('API request failed', error, { tag: 'api' });
dev.warn('Cache miss', cacheKey, { tag: 'cache' });

// Advanced methods
dev.table([{ name: 'John', age: 30 }, { name: 'Jane', age: 25 }]);
dev.trace('Stack trace');
dev.dir({ foo: 'bar' });

// Grouping
dev.group('My Group');
dev.log('Inside group');
dev.groupEnd();

dev.groupCollapsed('Collapsed Group');
dev.log('Hidden by default');
dev.groupEnd();

// Timing
dev.time('operation');
// ... your code ...
dev.timeEnd('operation');
dev.timeLog('operation', 'Checkpoint');

// Counting
dev.count('clicks');
dev.count('clicks');
dev.countReset('clicks');

// Assertions
dev.assert(value === expected, 'Values do not match');

// Other methods
dev.clear();
dev.dirxml(document.body);

Default Export

You can also use the default export:

import dev from '@onamfc/developer-log';

dev.log('Using default export');

How it Works

The package checks process.env.NODE_ENV and suppresses all output when it equals 'production'. In all other environments (development, test, etc.), it behaves exactly like the native console methods.

Tag-Based Filtering

Control which logs are displayed during development using optional tags. This is useful for filtering logs by category, feature, or component.

Configuration

Option 1: Auto-Load (Recommended)

Simply create a config file in your project root with one of these names:

  • dev-log.config.json
  • .devlogrc.json
  • .devlogrc

The config file will be automatically loaded when the module is imported (in non-production environments only).

{
  "disabledTags": ["verbose", "debug", "trace"]
}

No additional code needed - just import and use:

import { dev } from '@onamfc/developer-log';

// Config already loaded automatically!
// All tags show except those in disabledTags
dev.log('Query executed', { tag: 'database' }); // Shows
dev.log('Verbose details', { tag: 'verbose' }); // Hidden

Option 2: Programmatic Configuration

For dynamic configuration or when you need to set tags based on runtime conditions:

import { dev } from '@onamfc/developer-log';

// Hide specific tags, show everything else
dev.configure({ disabledTags: ['verbose', 'debug', 'trace'] });

Where to place dev.configure():

  • In your main entry point (index.ts, app.ts, server.ts, main.ts)
  • Before any code that uses tagged logs
  • In framework initialization:
    • Express/Node.js: Top of your main server file
    • Next.js: In _app.tsx or layout.tsx
    • React: In index.tsx or App.tsx
    • NestJS: In main.ts before app.listen()

Option 3: Explicit File Loading

Load a config file from a specific path:

import { dev } from '@onamfc/developer-log';

dev.loadConfig('./config/dev-log.config.json');

Config File Format:

{
  "disabledTags": ["verbose", "debug", "trace"]
}

All tags are shown by default. Only tags in disabledTags will be hidden.

Configuration Priority:

If multiple configuration methods are used, the last one wins:

  1. Auto-loaded config (happens first, at module import)
  2. Programmatic dev.configure() (overrides auto-loaded config)
  3. Explicit dev.loadConfig() (overrides everything)

Using Tags

Add a tag by passing an options object as the last parameter:

// Tagged logs - only show if tag is enabled
dev.log('Database query executed', result, { tag: 'database' });
dev.error('API request failed', error, { tag: 'api' });
dev.warn('Authentication timeout', { tag: 'auth' });

// Untagged logs - always show regardless of configuration
dev.log('Application started');
dev.error('Critical error occurred', error);

Filtering Behavior

  • No configuration: All logs (tagged and untagged) are displayed
  • With disabledTags: All logs except those with disabled tags are displayed
  • Untagged logs: Always displayed regardless of configuration
  • Production environment: All logs are suppressed (tags have no effect)

Practical Examples

Scenario 1: Hiding noisy logs

// You have lots of verbose logs that clutter your console
dev.log('Verbose cache details', data, { tag: 'verbose' });
dev.log('Debug information', { tag: 'debug' });
dev.log('Trace data', { tag: 'trace' });
dev.log('User logged in', { tag: 'auth' }); // Important log

// Hide the noisy tags, but keep everything else
dev.configure({ disabledTags: ['verbose', 'debug', 'trace'] });
// Now: auth and all other logs show, but verbose/debug/trace are hidden

Scenario 2: Production-like logging in development

// Disable development-only debug logs
dev.log('SQL Query: SELECT * FROM users', { tag: 'sql-debug' });
dev.log('Cache hit ratio: 85%', { tag: 'performance-debug' });
dev.error('Payment failed', error, { tag: 'payment' }); // Important

// Simulate production logging
dev.configure({ disabledTags: ['sql-debug', 'performance-debug'] });
// Only important logs show, like production

Scenario 3: Dynamic configuration via environment

// In your main app entry point
if (process.env.DISABLE_TAGS) {
  dev.configure({
    disabledTags: process.env.DISABLE_TAGS.split(',')
  });
}

// Run with: DISABLE_TAGS=verbose,debug npm start
// All logs show except verbose and debug

Supported Methods

All standard console methods are supported:

  • log - General logging
  • error - Error messages
  • warn - Warning messages
  • info - Informational messages
  • debug - Debug messages
  • trace - Stack trace
  • table - Tabular data
  • dir - Object inspection
  • dirxml - XML/HTML element inspection
  • group - Create a message group
  • groupCollapsed - Create a collapsed message group
  • groupEnd - End a message group
  • clear - Clear the console
  • count - Count occurrences
  • countReset - Reset counter
  • assert - Assertion testing
  • time - Start a timer
  • timeEnd - End a timer
  • timeLog - Log elapsed time

Why Use This?

  • Clean production builds: No need to manually remove debug statements
  • Granular log control: Filter logs by category/feature using tags during development
  • Reduce noise: Focus on relevant logs without commenting out code
  • Type-safe: Full TypeScript support
  • Zero dependencies: Lightweight and efficient
  • Drop-in replacement: Works exactly like console in development
  • Performance: No overhead in production (all methods are no-ops)
  • Flexible filtering: Configure via code or config file

Migration from console

Simply replace console with dev:

// Before
console.log('Debug message');
console.error('Error message');
console.table(data);

// After
import { dev } from '@onamfc/developer-log';

dev.log('Debug message');
dev.error('Error message');
dev.table(data);

Optional: Add tags for better log organization

// After migration, optionally add tags
dev.log('User authenticated', user, { tag: 'auth' });
dev.log('Verbose trace data', data, { tag: 'verbose' });
dev.warn('Debug information', { tag: 'debug' });

// Hide noisy tags to clean up your console
dev.configure({ disabledTags: ['verbose', 'debug'] });
// Now 'verbose' and 'debug' logs are hidden, everything else shows

Platform Support

Node.js

Full support for all features including:

  • ✅ Tag-based filtering
  • ✅ Auto-load config from files
  • ✅ Programmatic configuration
  • ✅ File-based configuration with loadConfig()

React Native / Browser

Basic logging works perfectly, with some limitations:

  • ✅ All console methods work (log, error, warn, etc.)
  • ✅ Tag-based filtering with programmatic configuration
  • ✅ Production environment suppression
  • ❌ Auto-load config files (Node.js file system not available)
  • dev.loadConfig() (Node.js file system not available)

React Native Usage:

import { dev } from '@onamfc/developer-log';

// Use programmatic configuration instead of file-based
dev.configure({ disabledTags: ['verbose', 'debug'] });

// Everything else works the same
dev.log('User logged in', { tag: 'auth' }); // Shows
dev.log('Verbose details', { tag: 'verbose' }); // Hidden
dev.error('API error', error, { tag: 'api' }); // Shows

TypeScript

This package is written in TypeScript and includes type definitions out of the box.

License

MIT