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

discord-webhook-kit

v0.1.0

Published

Modern, TypeScript-first Discord Webhook client

Readme

discord-webhook-kit

Modern, TypeScript-first Discord Webhook client with full type safety, ESM support, and modern features.

Features

  • TypeScript-first: Full type safety with comprehensive type definitions
  • Modern: ESM and CJS dual build support
  • Safe defaults: Prevents accidental @everyone mentions
  • Rate limit handling: Automatic retry with configurable backoff
  • Lightweight: Minimal dependencies (only undici)
  • Simple API: Easy to use and predictable
  • EmbedBuilder: Fluent API for building embeds with method chaining
  • AlertClient: Pre-configured alerts for error monitoring (info/success/warn/error)

Installation

npm install discord-webhook-kit

Quick Start

import { WebhookClient } from "discord-webhook-kit";

const webhook = new WebhookClient(
  "https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN"
);

// Send a simple message
await webhook.send("Hello, Discord!");

// Send with custom username and avatar
await webhook.send({
  content: "Hello from custom bot!",
  username: "My Bot",
  avatar_url: "https://example.com/avatar.png",
});

Usage Examples

Simple Text Message

const webhook = new WebhookClient(WEBHOOK_URL);
await webhook.send("Hello, World!");

Rich Embed Message

await webhook.send({
  content: "Check out this embed!",
  embeds: [
    {
      title: "Embed Title",
      description: "This is the embed description",
      color: 0x00ff00, // Green color
      fields: [
        { name: "Field 1", value: "Value 1", inline: true },
        { name: "Field 2", value: "Value 2", inline: true },
      ],
      footer: {
        text: "Footer text",
      },
      timestamp: new Date().toISOString(),
    },
  ],
});

Using EmbedBuilder (Method Chaining)

import { WebhookClient, EmbedBuilder } from "discord-webhook-kit";

const embed = new EmbedBuilder()
  .setTitle("My title here")
  .setAuthor(
    "Author here",
    "https://cdn.discordapp.com/embed/avatars/0.png",
    "https://www.google.com"
  )
  .setURL("https://www.google.com")
  .addField("First field", "this is inline", true)
  .addField("Second field", "this is not inline")
  .setColor("#00b0f4")
  .setThumbnail("https://cdn.discordapp.com/embed/avatars/0.png")
  .setDescription("Oh look a description :)")
  .setImage("https://cdn.discordapp.com/embed/avatars/0.png")
  .setFooter(
    "Hey its a footer",
    "https://cdn.discordapp.com/embed/avatars/0.png"
  )
  .setTimestamp();

await webhook.send({ embeds: [embed] });

With Default Options

const webhook = new WebhookClient(WEBHOOK_URL, {
  username: "Notification Bot",
  avatarUrl: "https://example.com/bot-avatar.png",
  retryOnRateLimit: true,
  maxRetries: 5,
  timeout: 10000,
});

// All messages will use the default username and avatar
await webhook.send("This uses default settings!");

Send to Thread

const webhook = new WebhookClient(WEBHOOK_URL, {
  threadId: "1234567890",
});

await webhook.send("Message sent to a specific thread!");

Disable Rate Limit Retry

const webhook = new WebhookClient(WEBHOOK_URL, {
  retryOnRateLimit: false,
});

try {
  await webhook.send("Message");
} catch (error) {
  if (error instanceof DiscordWebhookError && error.isRateLimit()) {
    console.log("Rate limited! Try again later.");
  }
}

API Reference

WebhookClient

new WebhookClient(webhookUrl: string, options?: WebhookClientOptions)

Constructor Options

| Option | Type | Default | Description | | ------------------ | --------- | ------- | ------------------------------------ | | username | string | - | Default username for all messages | | avatarUrl | string | - | Default avatar URL for all messages | | wait | boolean | true | Wait for server confirmation | | threadId | string | - | Thread ID to send messages to | | retryOnRateLimit | boolean | true | Automatically retry on rate limit | | maxRetries | number | 3 | Maximum retry attempts on rate limit | | timeout | number | 30000 | Request timeout in milliseconds |

Methods

send(content: string | WebhookMessage): Promise<WebhookResponse>

Sends a message to the Discord webhook.

// String shorthand
await webhook.send("Hello!");

// Full message object
await webhook.send({
  content: "Hello!",
  username: "Custom Name",
  embeds: [{ title: "Embed" }],
});
getMaskedUrl(): string

Returns a masked version of the webhook URL safe for logging.

console.log(webhook.getMaskedUrl());
// Output: /webhooks/1234567890/abcd...wxyz

WebhookMessage

| Field | Type | Description | | ------------------ | ----------------- | -------------------------------- | | content | string | Message content (max 2000 chars) | | username | string | Override webhook username | | avatar_url | string | Override webhook avatar | | tts | boolean | Text-to-speech message | | embeds | WebhookEmbed[] | Array of embeds (max 10) | | allowed_mentions | AllowedMentions | Mention control | | flags | number | Message flags | | thread_name | string | Thread name (for forum channels) | | applied_tags | string[] | Tag IDs (for forum channels) |

WebhookEmbed

| Field | Type | Description | | ------------- | --------------------- | ---------------------------- | | title | string | Embed title (max 256 chars) | | description | string | Embed description (max 4096) | | url | string | URL for title link | | color | number | Color code (decimal) | | timestamp | string | ISO8601 timestamp | | footer | WebhookEmbedFooter | Footer object | | image | WebhookEmbedMedia | Image object | | thumbnail | WebhookEmbedMedia | Thumbnail object | | author | WebhookEmbedAuthor | Author object | | fields | WebhookEmbedField[] | Fields array (max 25) |

EmbedBuilder

Builder class for creating embeds with method chaining.

| Method | Description | | --------------------------------- | -------------------------------- | | setTitle(title) | Set embed title | | setDescription(description) | Set embed description | | setURL(url) | Set embed URL | | setColor(color) | Set color (hex string or number) | | setAuthor(name, iconUrl?, url?) | Set author info | | setThumbnail(url) | Set thumbnail image | | setImage(url) | Set main image | | setFooter(text, iconUrl?) | Set footer | | setTimestamp(timestamp?) | Set timestamp (default: now) | | addField(name, value, inline?) | Add a field | | addFields(...fields) | Add multiple fields | | toJSON() | Convert to plain embed object |

DiscordWebhookError

Custom error class for Discord API errors.

try {
  await webhook.send("Message");
} catch (error) {
  if (error instanceof DiscordWebhookError) {
    console.log("Status:", error.status);
    console.log("Message:", error.message);
    console.log("Raw body:", error.rawBody);
    console.log("Request ID:", error.requestId);
    console.log("Is rate limit:", error.isRateLimit());
  }
}

AlertClient (Error Alerting)

AlertClient provides a convenient way to send formatted alerts to Discord, perfect for error monitoring and application notifications.

import { AlertClient } from "discord-webhook-kit";

const alert = new AlertClient(WEBHOOK_URL, {
  appName: "My API",
  environment: "production",
  username: "Alert Bot",
  avatarUrl: "https://example.com/avatar.png",
});

// Info alert (blue)
await alert.info("User logged in", {
  fields: [{ name: "User ID", value: "12345" }],
});

// Success alert (green)
await alert.success("Payment completed", {
  fields: [
    { name: "Amount", value: "$100.00" },
    { name: "Order ID", value: "ORD-123" },
  ],
});

// Warning alert (yellow)
await alert.warn("High memory usage detected", {
  fields: [{ name: "Usage", value: "85%" }],
});

// Error alert (red) - with Error object auto-formatting
try {
  await riskyOperation();
} catch (err) {
  await alert.error(err); // Auto-formats Error with stack trace
}

// Error alert with custom message and error
await alert.error("Database operation failed", {
  error: caughtError,
  fields: [{ name: "Query", value: "SELECT * FROM users" }],
});

AlertClient Options

| Option | Type | Default | Description | | ------------- | -------- | --------- | -------------------------------- | | appName | string | "Alert" | Application name shown in title | | environment | string | - | Environment (e.g., "production") | | username | string | - | Default webhook username | | avatarUrl | string | - | Default webhook avatar |

Alert Colors

| Level | Color | Hex Code | | --------- | ------ | --------- | | info | Blue | #3498db | | success | Green | #00ff1d | | warn | Yellow | #f1c40f | | error | Red | #ff0000 |

Error Auto-Formatting

When passing an Error object to alert.error(), it automatically:

  • Extracts error name and message
  • Includes code and status properties if present
  • Formats stack trace in a code block
  • Respects Discord's field limits (auto-trims long content)

Safe Defaults

By default, discord-webhook-kit disables @everyone and @here mentions to prevent accidental mass pings:

// Default: allowed_mentions is set to { parse: [] }
await webhook.send("@everyone Hello!"); // Won't ping everyone

// To enable mentions, explicitly set allowed_mentions
await webhook.send({
  content: "@everyone Hello!",
  allowed_mentions: { parse: ["everyone"] },
});

Requirements

  • Node.js 18.0.0 or higher

Related

License

MIT