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

namespaced-logger

v1.0.2

Published

Small, clean, zero-dependency, namespace-aware logger with env-based enablement and pluggable transports.

Readme

GitHub License GitHub commit activity GitHub Actions Workflow Status GitHub Release GitHub Release Date GitHub Issues or Pull Requests GitHub watchers GitHub forks GitHub Repo stars NPM Version NPM Type Definitions NPM Downloads Node Current

Small, clean, zero-dependency, namespace-aware logger with env-based enablement and pluggable transports.

namespaced-logger is inspired by tools like debug and pino, but keeps things intentionally simple:

  • Namespaced loggers – create loggers with namespaces and unlimited nested child loggers ("app", "app:db", "worker:queue", …).
  • Popular runtimes support – works in Node.js, Deno, Bun, and modern browsers.
  • Environment Variable-based control – enable/disable loggers via NAMESPACED_LOGGER_ENABLE and set level via NAMESPACED_LOGGER_LEVEL.
  • Multiple log levelsdebug, info, warn, error.
  • Pluggable transports – built‑in console transport, plus custom transports support.
  • Colorized output for Console – human‑friendly colors in TTYs, plain text when not.
  • ESM‑first – designed for modern JavaScript/TypeScript projects.
  • TypeScript types included – written in TS entirely, with types included.
  • Zero dependencies – no runtime dependencies, tiny bundle size.

Installation

npm install namespaced-logger
# or
pnpm add namespaced-logger
# or
yarn add namespaced-logger

Quick start

import { createLogger } from 'namespaced-logger'

const log = createLogger('app')
log.info('App initialized!')

const serverLog = log.child('server')
serverLog.info('server starting on port %d', 3000)
serverLog.warn('deprecated option %s used', '--foo')
serverLog.error('unexpected error: %j', { code: 'E_FAIL', retry: false })

const dbLog = log.child('db')
dbLog.debug('connecting to database at %s', 'localhost:5432')
dbLog.info('database connected')

Example output (colors in a TTY; simplified here):

02:03:15.345 INFO  app - App initialized!
02:03:15.346 INFO  app:server - server starting on port 3000
02:03:15.347 WARN  app:server - deprecated option --foo used
02:03:15.348 ERROR app:server - unexpected error: {"code":"E_FAIL","retry":false}
02:03:15.349 DEBUG app:db - connecting to database at localhost:5432
02:03:15.350 INFO  app:db - database connected

API

createLogger(namespace: string, options?: Options): Logger

Create a namespaced logger instance.

  • namespace: The namespace for the logger (e.g., "app").
  • options (optional): Configuration options for the logger.
    • transports (optional): Array of personalized transports to use.
    • disableBuiltinTransports (optional): Array of built-in transport names to disable. For example, ['console'] disables the built-in console transport.

A Logger instance exposes:

  • log.info(message: unknown, ...args: unknown[]): void
  • log.warn(message: unknown, ...args: unknown[]): void
  • log.error(message: unknown, ...args: unknown[]): void
  • log.debug(message: unknown, ...args: unknown[]): void
  • log.child(name: string): Logger – create a child logger with an extended namespace. A child logger inherits the parent's configuration and can have its own child.

Message formatting

namespaced-logger supports basic printf-style formatting:

  • %s - String
  • %d - Number
  • %j - JSON-stringify the next argument.
  • %% – escaped percent sign (literal %)

Any extra arguments that are not consumed by placeholders in the first argument are preserved. When the first argument is not a string, it’s converted to a string, and all other arguments are preserved as extra arguments. In console, extra arguments are logged as they are after the formatted message.:

log.info('User %s logged in from %s', 'alice', '192.168.1.1')
log.debug('Processing data: %j', { id: 123, value: 'test' })
log.warn('Disk space low: %d%% remaining', 5)
log.error('Unexpected error occurred: %s', 'Connection timed out')
log.info('Server started on port %d', 8080)
log.info('Simple message without formatting')
log.info('Show %s', 'data', { event: 'user_login', user: 'alice' }) // Extra args preserved and logged as it is in console
log.info({ event: 'user_login', user: 'alice' }, 'alice') // first arg not string

Example output:

02:03:15.345 INFO  app - User alice logged in from 192.168.1.1
02:03:15.346 DEBUG app - Processing data: {"id":123,"value":"test"}
02:03:15.347 WARN  app - Disk space low: 5% remaining
02:03:15.348 ERROR app - Unexpected error occurred: Connection timed out
02:03:15.349 INFO  app - Server started on port 8080
02:03:15.350 INFO  app - Simple message without formatting
02:03:15.351 INFO  app - Show data { event: 'user_login', user: 'alice' }
02:03:15.351 INFO  app - [object Object] alice

Colors

When process.stdout.isTTY is true (running in a real terminal), namespaced-logger uses ANSI colors to colorize log levels for better readability:

  • DEBUG - Cyan
  • INFO - Green
  • WARN - Yellow
  • ERROR - Red

In non‑TTY environments (piped to a file, many CI systems, etc.), colors are automatically disabled so logs stay clean and parseable.

Log enabling and levels

Environment variables NAMESPACED_LOGGER_ENABLE and NAMESPACED_LOGGER_LEVEL can be used to control which namespace loggers are enabled and the minimum log level.

Environment Variable Set

  • Browser

    localStorage.setItem('NAMESPACED_LOGGER_ENABLE', 'app')
    localStorage.setItem('NAMESPACED_LOGGER_LEVEL', 'debug')
  • Node.js / Deno / Bun

    export NAMESPACED_LOGGER_ENABLE='app'
    export NAMESPACED_LOGGER_LEVEL='debug'

Namespace enabling

You can control which loggers are enabled via the NAMESPACED_LOGGER_ENABLE environment variable. It supports glob-style patterns to match namespaces:

  • '*' enables loggers of all namespaces.
  • '' (empty string) disables all loggers.
  • 'app1,app2' enables loggers for the specified namespaces app1 and app2 only.

Log levels

You can set the minimum log level via the NAMESPACED_LOGGER_LEVEL environment variable. Supported levels are:

  • debug: all log messages are shown.
  • info: only info, warn, and error messages are shown.
  • warn: only warn and error messages are shown.
  • error: only error messages are shown.

Default level is info if not set.

Error logging

You can log errors directly:

try {
  await doWork()
}
catch (err) {
  log.error('work failed: %s', (err as Error).message, err)
}

Because extra arguments are preserved, you typically get:

  • a readable message (work failed: )
  • the full Error object (with stack) available as an extra argument for inspection or log collection

Pluggable transports

You can create custom transports by providing a log function in the transport configuration:

import { createLogger } from 'namespaced-logger'

const log = createLogger('app', {
  transports: [{
    name: 'customTransport',
    enable: true, // Override environment variable NAMESPACED_LOGGER_ENABLE
    level: 'debug', // Override environment variable NAMESPACED_LOGGER_LEVEL
    log: (event: LogEvent) => {
      // Custom transport logic here
      // e.g., send logs to a remote server
    }
  }]
})

Contributing

Contributions are welcome! If you have ideas, bug fixes, or improvements, please open an issue or submit a pull request on the GitHub repository.

Give a ⭐️ if this project helped you!

License

This project is licensed under the MIT License. See the LICENSE file for more details.