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

@slackgram/logger

v1.0.17

Published

TypeScript-first logger for Node.js with file rotation and webhook support for Discord/Slack/Telegram

Readme

@slackgram/logger

@slackgram/logger is a modern, dependency‑free, TypeScript‑first logging system that works in Node.js and can be bundled into browser/front‑end apps. It provides colorful, human‑friendly logs in development and structured JSON logs in production, with optional file logging and real‑time tracking via Slack / Telegram (and Discord) webhooks/bots.

Features

  • Dependency‑free: Uses only built‑in Node APIs when available.
  • Log levels: debug, info, warn, error.
  • Optional emojis and colored console output.
  • Timestamps by default (ISO 8601 with milliseconds).
  • File logging (Node.js):
    • Configurable path.
    • Rotation: "1H", "1D", "1W".
    • Retention by max number of files.
    • Buffered, async, non‑blocking writes.
    • Optional pretty JSON lines.
  • Hooks system:
    • Discord / Slack / Telegram integrations.
    • Hook thresholds via hooks.minLevel.
    • Fire asynchronously; failures are swallowed (best‑effort).
  • Pretty formatting:
    • Objects / arrays via safe JSON.stringify.
    • Error → stack.
    • BigInt"123n".
    • Node Buffer"<Buffer length=...>".
  • Convenience utilities:
    • log.time(label, asyncFn) → times async code.
    • log.group() / log.groupEnd() for indentation‑based grouping.
    • log.tag("HTTP") to create tagged child loggers.
  • Environment aware:
    • development → colorful text logs.
    • production → one JSON object per console line.

Installation

Add the files to your project (or publish to npm and install from there):

pnpm add @slackgram/logger
# or
npm install @slackgram/logger
# or
yarn add @slackgram/logger

If using this repo directly, just reference the entry file in your imports (e.g. ./src/index).

Basic usage

import log, { config } from '@slackgram/logger';

config({
  env: 'development',
  minLevel: 'info',
  debug: true,
});

log.info('Server started on port', 3000);
log.warn('Cache miss for key', 'user:123');
log.error('Unexpected error', new Error('boom'));
log.debug('Raw payload', { foo: 'bar' });

Tagging

import log, { tag } from '@slackgram/logger';

const httpLog = tag('HTTP');

httpLog.info('GET /users', { userId: 42 });
httpLog.error('Request failed', new Error('timeout'));

Timing async work

await log.time('user.fetch', async () => {
  // some async work
});

This will emit debug‑level logs like:

  • ⏱️ user.fetch - start
  • ⏱️ user.fetch - done in 37ms

Grouping logs

log.group('Processing batch #1');
log.info('Step 1');
log.info('Step 2');
log.groupEnd();

In development this adds indentation to grouped logs to make them visually distinct.

File logging (Node.js)

import log, { config } from '@slackgram/logger';

config({
  file: {
    enabled: true,
    filePath: 'logs/app.log',
    rotation: {
      strategy: '1D', // rotate daily
      maxFiles: 7, // keep last 7
    },
    flushIntervalMs: 2000,
    prettyJson: true,
  },
});

File logging is no‑op in browser environments; it only activates when a Node‑like process.cwd() is available.

You can force a flush (for example, before process exit):

await log.flush();

Webhook hooks (Discord, Slack, Telegram)

import { config } from '@slackgram/logger';

config({
  hooks: {
    minLevel: 'error', // only trigger on error and above
    discord: {
      enabled: true,
      webhookUrl: 'https://discord.com/api/webhooks/...',
    },
    slack: {
      enabled: true,
      webhookUrl: 'https://hooks.slack.com/services/...',
    },
    telegram: {
      enabled: true,
      botToken: 'BOT_TOKEN',
      chatId: 'CHAT_ID',
    },
  },
});

Hooks are fired asynchronously and are best‑effort; network/HTTP errors are ignored so logging never blocks your application.

Setting hooks via environment variables

Keep webhook URLs and tokens out of code by using environment variables. In Node.js, read process.env when calling config():

import { config } from '@slackgram/logger';

config({
  hooks: {
    minLevel: process.env.MB_LOG_HOOK_LEVEL || 'warn',
    discord: {
      enabled: !!process.env.DISCORD_WEBHOOK_URL,
      webhookUrl: process.env.DISCORD_WEBHOOK_URL || '',
    },
    slack: {
      enabled: !!process.env.SLACK_WEBHOOK_URL,
      webhookUrl: process.env.SLACK_WEBHOOK_URL || '',
    },
    telegram: {
      enabled: !!(process.env.TELEGRAM_BOT_TOKEN && process.env.TELEGRAM_CHAT_ID),
      botToken: process.env.TELEGRAM_BOT_TOKEN || '',
      chatId: process.env.TELEGRAM_CHAT_ID || '',
    },
  },
});

Suggested env vars

| Variable | Used by | Description | |----------|---------|-------------| | DISCORD_WEBHOOK_URL | Discord | Incoming webhook URL from Discord server settings | | SLACK_WEBHOOK_URL | Slack | Incoming webhook URL from Slack app (e.g. https://hooks.slack.com/services/...) | | TELEGRAM_BOT_TOKEN | Telegram | Bot token from @BotFather | | TELEGRAM_CHAT_ID | Telegram | Chat or group ID (e.g. from getUpdates after messaging the bot) | | MB_LOG_HOOK_LEVEL | All | Minimum level to send to hooks: debug, info, warn, error (optional) | | MB_LOGGER_TELEGRAM_API | Telegram | Override Telegram API base URL (optional, default https://api.telegram.org) |

Setting env vars when running

Windows (cmd):

set DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
set SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...
set TELEGRAM_BOT_TOKEN=123456789:ABC...
set TELEGRAM_CHAT_ID=-1001234567890
set MB_LOG_HOOK_LEVEL=warn
node index.mjs

Windows (PowerShell):

$env:DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..."
$env:SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."
$env:TELEGRAM_BOT_TOKEN="123456789:ABC..."
$env:TELEGRAM_CHAT_ID="-1001234567890"
$env:MB_LOG_HOOK_LEVEL="warn"
node index.mjs

Linux / macOS:

export DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..."
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."
export TELEGRAM_BOT_TOKEN="123456789:ABC..."
export TELEGRAM_CHAT_ID="-1001234567890"
export MB_LOG_HOOK_LEVEL="warn"
node index.mjs

Or use a .env file with a loader (e.g. dotenv) and load it before calling config(); never commit .env to version control.

Configuration reference

import type { LoggerConfig } from '@slackgram/logger';

const cfg: LoggerConfig = {
  env: 'development', // 'development' | 'production' | 'test'
  minLevel: 'info', // 'debug' | 'info' | 'warn' | 'error'
  silent: false,
  debug: false,
  colors: true,

  levels: {
    debug: { enabled: true, emoji: '🐛' },
    info: { enabled: true, emoji: 'ℹ️' },
    warn: { enabled: true, emoji: '⚠️' },
    error: { enabled: true, emoji: '⛔' },
  },

  file: {
    enabled: true,
    filePath: 'logs/app.log',
    rotation: {
      strategy: '1D', // '1H' | '1D' | '1W'
      maxFiles: 7,
    },
    flushIntervalMs: 2000,
    prettyJson: true,
  },

  hooks: {
    minLevel: 'error',
    discord: { enabled: true, webhookUrl: '' },
    slack: { enabled: true, webhookUrl: '' },
    telegram: { enabled: false, botToken: '', chatId: '' },
  },

  timestampFn: () => new Date().toISOString(),
};

TypeScript & JavaScript

  • In TypeScript, import from the package name or file path; types are defined in types.ts and surfaced via the bundled declaration file.
  • In JavaScript, you can still import the default logger and call the same methods; you just won’t get static type checking unless your tooling reads .d.ts files.