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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@zzazz/slack

v1.0.8

Published

Production-grade, framework-agnostic error alerting library for Slack with first-class NestJS and Express support

Downloads

709

Readme

@zzazz/slack

NPM Version License: MIT

Production-grade, framework-agnostic error alerting library for Slack with first-class support for NestJS and Express applications.

🚀 Features

| Feature | Description | | --------------------------- | ----------------------------------------------------------------- | | ✅ Plug-and-play | Initialize once, capture errors automatically | | ✅ Framework-agnostic | Works with any Node.js application | | ✅ First-class integrations | NestJS module and Express middleware included | | ✅ Non-blocking | Fire-and-forget async alerting with retry logic | | ✅ Slack Block Kit | Beautiful, structured messages with severity indicators | | ✅ Production-safe | Rate limiting, sanitization, and graceful error handling | | ✅ Severity levels | info, warning, error, critical | | ✅ Smart mentions | Conditional @user or @usergroup tagging | | ✅ Auto-capture | Uncaught exceptions and unhandled promise rejections | | ✅ Secure | Automatic masking of sensitive data (tokens, passwords, API keys) | | ✅ TypeScript | Full type safety and IntelliSense support |

📦 Installation

npm install @zzazz/slack
yarn add @zzazz/slack
pnpm add @zzazz/slack

🎯 Quick Start

Plain Node.js

import { SlackAlerts } from '@zzazz/slack';

// Initialize at app startup
SlackAlerts.init({
  webhookUrl: process.env.SLACK_WEBHOOK_URL!,
  defaultChannel: '#alerts',
  appName: 'my-app',
  environment: 'production',
  enabled: true,
});

// Send alerts
await SlackAlerts.error(new Error('Something went wrong'));
await SlackAlerts.critical('Database connection lost');
await SlackAlerts.warning('High memory usage detected');
await SlackAlerts.info('Deployment completed');

NestJS

// app.module.ts
import { Module } from '@nestjs/common';
import { SlackAlertsModule, SlackExceptionFilter } from '@zzazz/slack';
import { APP_FILTER } from '@nestjs/core';

@Module({
  imports: [
    SlackAlertsModule.forRoot({
      webhookUrl: process.env.SLACK_WEBHOOK_URL!,
      defaultChannel: '#backend-alerts',
      appName: 'accounts-service',
      environment: 'production',
      channelMappings: {
        '#backend-alerts': '@backend-team',
      },
      mentionOnSeverity: ['critical'],
    }),
  ],
  providers: [
    {
      provide: APP_FILTER,
      useClass: SlackExceptionFilter,
    },
  ],
})
export class AppModule {}

Express

import express from 'express';
import { SlackAlerts, slackErrorMiddleware, asyncHandler } from '@zzazz/slack';

const app = express();

// Initialize
SlackAlerts.init({
  webhookUrl: process.env.SLACK_WEBHOOK_URL!,
  defaultChannel: '#alerts',
  appName: 'api-gateway',
  environment: 'production',
});

// Routes
app.get(
  '/users/:id',
  asyncHandler(async (req, res) => {
    const user = await fetchUser(req.params.id);
    res.json(user);
  })
);

// Error middleware (must be after routes)
app.use(slackErrorMiddleware());

app.listen(3000);

🔧 Configuration

SlackAlertsConfig

SlackAlerts.init({
  // Required
  webhookUrl: string;          // Slack webhook URL
  appName: string;              // Your application name
  environment: string;          // e.g., 'production', 'staging'

  // Optional
  defaultChannel?: string;      // Default: '#alerts'
  enabled?: boolean;            // Default: true
  maxAlertsPerMinute?: number;  // Default: 10 (rate limiting)

  // Channel-to-team mappings for mentions
  channelMappings?: {
    '#backend-alerts': '@backend-team',
    '#critical-alerts': '@oncall',
  };

  // Severities that trigger mentions
  mentionOnSeverity?: Severity[];  // Default: ['critical']

  // Custom sanitization function
  sanitize?: (data: unknown) => unknown;

  // Additional sensitive fields to mask
  sensitiveFields?: string[];  // Default: ['password', 'token', 'authorization', ...]
});

📊 Severity Levels

| Severity | Emoji | Use Case | Auto-mention | | ---------- | ----- | ------------------------------------------- | ------------------- | | info | ℹ️ | Informational messages, startup events | No | | warning | ⚠️ | Non-critical issues, degraded performance | No | | error | ❌ | Application errors, failed operations | No | | critical | 🚨 | System failures, data loss, security issues | Yes (if configured) |

🎨 Usage Examples

Manual Error Reporting

try {
  await processPayment(userId, amount);
} catch (error) {
  await SlackAlerts.critical(error as Error, {
    channel: '#payments-alerts',
    metadata: {
      userId,
      amount,
      timestamp: new Date().toISOString(),
    },
    tags: ['payment', 'critical'],
    mention: '@payments-oncall',
  });
  throw error;
}

Custom Severity

await SlackAlerts.alert('warning', 'API rate limit approaching', {
  metadata: {
    currentRate: 950,
    limit: 1000,
  },
  tags: ['rate-limiting', 'api'],
});

With Metadata

await SlackAlerts.error(error, {
  severity: 'critical',
  metadata: {
    userId: '12345',
    action: 'checkout',
    cartValue: 599.99,
    paymentMethod: 'credit_card',
  },
  tags: ['payment', 'checkout'],
});

Auto-Capture Global Errors

The library automatically captures:

  • Uncaught exceptions
  • Unhandled promise rejections
// This will be automatically sent to Slack
throw new Error('Uncaught exception');

// This will also be automatically sent
Promise.reject(new Error('Unhandled rejection'));

🔐 Security & Sanitization

Automatic Masking

The library automatically masks sensitive data:

const error = new Error('Failed: password=secret123 token=abc123');
await SlackAlerts.error(error);
// Sent to Slack: "Failed: password=***REDACTED*** token=***REDACTED***"

Automatically masked patterns:

  • Bearer tokens
  • JWT tokens
  • API keys (sk**, pk**)
  • AWS keys (AKIA...)
  • Password fields
  • Authorization headers

Custom Sanitization

SlackAlerts.init({
  webhookUrl: '...',
  appName: 'my-app',
  environment: 'production',

  // Custom sanitizer
  sanitize: data => {
    // Your custom logic
    return sanitizedData;
  },

  // Additional sensitive fields
  sensitiveFields: ['ssn', 'creditCard', 'customSecret'],
});

⚡ Performance & Reliability

Non-Blocking

All alerts are sent asynchronously and never block your application flow:

await SlackAlerts.error(error); // Returns immediately
// Your app continues without waiting for Slack

Retry Logic

Failed alerts are automatically retried with exponential backoff:

  • Max attempts: 3
  • Initial delay: 1s
  • Max delay: 5s

Rate Limiting

Prevents alert spam with configurable rate limits:

SlackAlerts.init({
  maxAlertsPerMinute: 15, // Max 15 alerts per minute
  // ...
});

Alerts exceeding the limit are silently dropped.

Graceful Degradation

If Slack is unreachable:

  • ✅ Your app continues running
  • ✅ Errors are logged to console
  • ✅ No exceptions are thrown

🧪 Testing

The library includes comprehensive unit tests:

npm test
npm run test:coverage

Coverage targets: 90%+ (branches, functions, lines, statements)

Mock for Testing

// In your tests
import { SlackAlerts } from '@zzazz/slack';

beforeEach(() => {
  SlackAlerts.init({
    webhookUrl: 'https://hooks.slack.com/services/TEST',
    appName: 'test-app',
    environment: 'test',
    enabled: false, // Disable in tests
  });
});

📚 API Reference

SlackAlerts

Methods

  • init(config: SlackAlertsConfig): void - Initialize the client
  • isInitialized(): boolean - Check initialization status
  • error(error: Error | string, options?: AlertOptions): Promise<void>
  • critical(error: Error | string, options?: AlertOptions): Promise<void>
  • warning(message: string, options?: AlertOptions): Promise<void>
  • info(message: string, options?: AlertOptions): Promise<void>
  • alert(severity: Severity, error: Error | string, options?: AlertOptions): Promise<void>

AlertOptions

interface AlertOptions {
  severity?: 'info' | 'warning' | 'error' | 'critical';
  channel?: string; // Override default channel
  metadata?: Record<string, unknown>; // Additional context
  tags?: string[]; // Categorization tags
  mention?: string; // @user or @usergroup to mention
}

🏗️ Architecture

@zzazz/slack/
├── src/
│   ├── client.ts           # Main SlackAlerts client
│   ├── types.ts            # TypeScript definitions
│   ├── formatter.ts        # Slack Block Kit formatter
│   ├── http-client.ts      # HTTP client for Slack API
│   ├── security.ts         # Sanitization utilities
│   ├── rate-limiter.ts     # Rate limiting logic
│   ├── retry.ts            # Retry with backoff
│   ├── integrations/
│   │   ├── nestjs/         # NestJS module & filter
│   │   └── express/        # Express middleware
│   └── __tests__/          # Unit tests
├── examples/               # Usage examples
└── dist/                   # Compiled output

🤝 Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass
  5. Submit a pull request

🔗 Links

💡 Tips

Getting a Slack Webhook URL

  1. Go to https://api.slack.com/apps
  2. Create a new app or select an existing one
  3. Enable "Incoming Webhooks"
  4. Click "Add New Webhook to Workspace"
  5. Select a channel and authorize
  6. Copy the webhook URL

Environment Variables

# .env
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/YOUR/WEBHOOK/URL
NODE_ENV=production

Best Practices

DO:

  • Initialize once at app startup
  • Use appropriate severity levels
  • Include relevant metadata
  • Test with enabled: false in development
  • Use channel mappings for team-specific alerts

DON'T:

  • Call init() multiple times unnecessarily
  • Send info/warning alerts for every request (too noisy)
  • Include sensitive data in metadata
  • Rely on alerts for critical application logic

👋 Support

For any doubts, please reach out to Vinit Shahdeo.

📊 Roadmap

  • [ ] Email fallback when Slack is down
  • [ ] Alert aggregation (group similar alerts)
  • [ ] Custom Slack Block Kit templates
  • [ ] Webhook signature verification
  • [ ] Alert dashboard and analytics

Built with ❤️ for production systems at ZZAZZ