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

@syntrojs/logger

v0.2.4-alpha

Published

๐Ÿ”ฅ Fast, simple, and developer-friendly logger for Node.js and Bun (ALPHA - Proof of Concept)

Readme

npm version License ๐Ÿš€ DUAL RUNTIME

Quality & Security:

CI CodeQL Mutation Testing Security Dependabot

Code Coverage:

Coverage Mutation Score


โš ๏ธ ALPHA VERSION

๐Ÿšจ This is an ALPHA version and proof of concept. Do not use in production!

  • โœ… Core functionality works - All transports, child loggers, and async context.
  • โœ… Well tested - 93.05% code coverage, 54.47% mutation score.
  • โš ๏ธ API may change - Breaking changes are expected.
  • โš ๏ธ Not production-ready - Missing CI/CD and stability improvements.

๐ŸŽฏ What is @syntrojs/logger?

@syntrojs/logger is a fast, simple, and developer-friendly logger for Node.js and Bun. It's designed for high performance and flexibility, offering beautiful, structured output with minimal configuration.

It works as a standalone library in any project or integrates seamlessly with the SyntroJS framework for automatic request correlation.


โœจ Core Features

  • โšก Blazing Fast: Optimized for performance (~75% of Pino's speed).
  • ๐ŸŽจ Beautiful & Flexible Output: Four built-in transports (JSON, Pretty, Compact, Classic).
  • ๐Ÿ”ง Type-Safe: Full TypeScript support out of the box.
  • ๐Ÿชถ Lightweight: Minimal dependencies (only chalk for colors).
  • ๐ŸŽฏ Simple & Fluent API: Chain methods to add rich, structured context to your logs.
  • ๐Ÿ—‚๏ธ Compliance & Business Ready: Attach deeply nested metadata for compliance (GDPR, HIPAA, PCI), business analytics, or internal workflows.
  • ๐Ÿš€ Dual Runtime: Works on both Node.js and Bun.

๐Ÿš€ Quick Start

1. Installation

npm install @syntrojs/logger@alpha
# or
pnpm add @syntrojs/logger@alpha

2. Basic Usage

Create a logger and start logging. It's that simple.

import { createLogger } from '@syntrojs/logger';

// Create a new logger instance
const logger = createLogger({ name: 'my-app' });

logger.info('Hello, world!');
logger.info({ userId: 123 }, 'User logged in');

For a shared, singleton instance across your application, use getLogger:

import { getLogger } from '@syntrojs/logger/registry';

// Gets or creates a shared logger for 'my-app'
const logger = getLogger('my-app');
logger.info('This message comes from a shared logger instance.');

3. Transports for Development vs. Production

Switch between human-readable logs in development and machine-readable JSON in production with a single option.

Development (pretty): Beautiful, colored output is the default.

const devLogger = createLogger({ name: 'dev-server', level: 'debug' });
devLogger.info({ userId: 123 }, 'User logged in');

Output:

[2025-01-01T12:00:00.000Z] [INFO] (dev-server): User logged in
{
  "userId": 123
}

Production (json): Structured JSON is essential for log aggregation systems.

const prodLogger = createLogger({ name: 'my-api', transport: 'json' });
prodLogger.info({ method: 'GET', path: '/users' }, 'Request received');

Output:

{"time":"2025-01-01T12:00:00.000Z","level":"info","message":"Request received","service":"my-api","method":"GET","path":"/users"}

๐Ÿ› ๏ธ Advanced Usage: The Fluent API for Rich Context

Add contextual data to your logs easily by chaining methods.

Child Loggers & Basic Context

Create specialized loggers that automatically include context like a module name, source, or a transaction ID for distributed tracing.

const logger = createLogger({ name: 'app' });

// Create a child logger with a 'module' binding
const dbLogger = logger.child({ module: 'database' });
dbLogger.info('Connected to database'); // Log includes "module": "database"

// Chain methods to add a source and transaction ID
const requestLogger = logger
  .withSource('payment-api')
  .withTransactionId('tx-payment-123');
  
requestLogger.info('Processing payment'); // Log includes source and transactionId

The Power of withRetention(): Compliance & Business Metadata

The .withRetention() method is the library's superpower. It allows you to attach any deeply nested JSON object to your logs. This is perfect for satisfying complex requirements for compliance, business analytics, and operations.

Why is this critical?

  • Compliance: Embed data for GDPR, HIPAA, PCI-DSS, etc., to track retention policies, audit trails, and data processing rules.
  • Business: Track marketing campaigns, user segments, product tiers, and other business-critical information.
  • Operations: Include team ownership, monitoring metrics, workflow stages, and alert configurations.

Example: Enterprise-Grade Logging

Hereโ€™s a logger configured for a payment service, embedding rich metadata for compliance, business, and internal monitoring.

import { createLogger } from '@syntrojs/logger';

const enterpriseLogger = createLogger({ name: 'payment-service' })
  .withRetention({
    // 1. Compliance Metadata (for auditors and legal)
    compliance: {
      regulations: {
        pci: {
          version: '3.2.1',
          level: 1,
          requirements: { encryption: 'AES-256', audit: { enabled: true, retention: '5-years' } }
        },
        gdpr: {
          articles: [6, 7, 32],
          dataProcessing: { legalBasis: 'contract', consent: 'explicit' }
        }
      }
    },
    // 2. Business Context (for analytics and product teams)
    business: {
      product: { id: 'payment-gateway', tier: 'enterprise' },
      vendor: { primary: 'stripe', backup: 'paypal' }
    },
    // 3. Operational Data (for engineering and SREs)
    internal: {
      team: { name: 'payments-engineering' },
      monitoring: { metrics: ['transaction-volume', 'error-rate', 'latency-p95'] }
    }
  });

// All logs from this logger will automatically include the full nested metadata
enterpriseLogger
  .withTransactionId('tx-payment-12345')
  .info({ amount: 299.99, currency: 'USD' }, 'Payment processed');

The resulting JSON log contains the info message and payload, plus the entire retention object with all its nested compliance, business, and internal data.

Managing Multiple Configurations with a Registry

For complex applications, you can define several logger configurations in a central registry and retrieve them on demand.

import { createLogger } from '@syntrojs/logger';

const loggerRegistry = {
  'simple': createLogger({ name: 'simple-app' }),
  'analytics': createLogger({ name: 'analytics-service' }).withRetention({
    compliance: { privacy: { gdpr: { anonymization: 'required' } } },
    business: { campaigns: { active: [{ id: 'summer-2024' }] } }
  }),
  'enterprise': enterpriseLogger // from the example above
};

function getLogger(name: 'simple' | 'analytics' | 'enterprise') {
  return loggerRegistry[name];
}

// Use loggers on-demand
getLogger('simple').info('User logged in');
getLogger('analytics').info({ event: 'purchase' }, 'Analytics event tracked');
getLogger('enterprise').withTransactionId('tx-abc').info('Enterprise log');

๐ŸŽจ Transports

Other Built-in Transports

Besides pretty and json, the logger includes:

  • compact: A single-line format perfect for CI/CD pipelines.
  • classic: A traditional Log4j-style format.
const logger = createLogger({ transport: 'compact' });
logger.info('Request processed', { statusCode: 200, latency: 45 });
// Output: [2025-01-01T12:00:00.000Z] [INFO] (ci-pipeline): Request processed | statusCode=200 latency=45

Composite Transport: Multiple Outputs

Send logs to multiple destinations at once, such as the console during development and a file for persistence.

import { createLogger, JsonTransport, PrettyTransport, CompositeTransport } from '@syntrojs/logger';

const logger = createLogger({
  name: 'my-app',
  transport: new CompositeTransport([
    new JsonTransport(),  // For log aggregation
    new PrettyTransport() // For the developer console
  ])
});

logger.info('This appears in both JSON and pretty format');

Custom Transports

You can easily create your own transport to send logs anywhere (e.g., a file, a webhook, or a monitoring service).

import { Transport, type LogEntry } from '@syntrojs/logger';
import * as fs from 'node:fs';

class FileTransport extends Transport {
  private logFile: string = './logs/app.log';

  log(entry: LogEntry): void {
    const line = JSON.stringify(entry) + '\n';
    fs.appendFileSync(this.logFile, line);
  }
}

const logger = createLogger({
  name: 'my-app',
  transport: new FileTransport()
});

logger.info('This log will be written to ./logs/app.log');

๐Ÿ“– API Reference

Logger Creation

  • createLogger(options): Creates a new, independent logger instance.
  • getLogger(name, options?): Retrieves or creates a shared, singleton logger instance from a global registry.

Logger Options

  • name (string): Service/application identifier.
  • level (string): Minimum log level to output (trace, debug, info, warn, error, fatal, silent). Default: info.
  • transport (string | Transport): Output format (pretty, json, compact, classic) or a custom transport instance. Default: pretty.

Logger Methods

  • logger.info(obj?, msg?, ...args): Logs an informational message.
  • logger.debug(...), logger.warn(...), logger.error(...), etc.
  • logger.child(bindings): Creates a new logger that inherits from the parent and includes the provided bindings object in all its logs.
  • logger.withSource(source): Returns a new logger instance with a source field.
  • logger.withTransactionId(id): Returns a new logger instance with a transactionId field.
  • logger.withRetention(rules): Returns a new logger instance with a retention field containing the provided metadata object.

๐Ÿ“„ License

Apache 2.0 - See LICENSE for details.