Discord.js is a powerful Node.js library that provides a comprehensive interface for interacting with the Discord API. It enables developers to create Discord bots and applications with full API coverage, featuring an object-oriented architecture with predictable abstractions, built-in WebSocket management for real-time events, REST API handling with rate limiting, and extensive TypeScript support.
npm install discord.jsimport { Client, GatewayIntentBits, Events } from 'discord.js';For CommonJS:
const { Client, GatewayIntentBits, Events } = require('discord.js');import { Client, GatewayIntentBits } from 'discord.js';
// Create a new client instance
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages]
});
// Ready event - fired when the client successfully connects
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
// Handle incoming interactions (slash commands, buttons, etc.)
client.on('interactionCreate', async interaction => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === 'ping') {
await interaction.reply('Pong!');
}
});
// Login to Discord with bot token
client.login(process.env.DISCORD_TOKEN);Discord.js is built around several key architectural patterns:
Client class serves as the main entry point and event hubCore client functionality for connecting to Discord, managing shards, and handling WebSocket connections. Essential for all bot operations.
class Client extends BaseClient {
constructor(options: ClientOptions);
login(token?: string): Promise<string>;
destroy(): Promise<void>;
// Properties
readonly user: ClientUser | null;
readonly guilds: GuildManager;
readonly channels: ChannelManager;
readonly users: UserManager;
}
interface ClientOptions {
intents: BitFieldResolvable<GatewayIntentsString, number>;
shardCount?: number | 'auto';
shards?: number | number[] | 'auto';
closeTimeout?: number;
restOptions?: Partial<RESTOptions>;
}Client & Connection Management
Comprehensive guild (server) management including channels, members, roles, permissions, and moderation features.
class Guild extends AnonymousGuild {
// Core properties
readonly id: Snowflake;
readonly name: string;
readonly ownerId: Snowflake;
readonly memberCount: number;
// Managers
readonly channels: GuildChannelManager;
readonly members: GuildMemberManager;
readonly roles: RoleManager;
readonly bans: GuildBanManager;
readonly invites: GuildInviteManager;
}
class GuildMember extends Base {
readonly user: User;
readonly roles: GuildMemberRoleManager;
readonly permissions: Readonly<PermissionsBitField>;
kick(reason?: string): Promise<GuildMember>;
ban(options?: BanOptions): Promise<GuildMember>;
}Message creation, editing, deletion, embeds, attachments, and reactions. Core functionality for bot communication.
class Message extends Base {
readonly content: string;
readonly author: User;
readonly channel: TextBasedChannel;
readonly attachments: Collection<Snowflake, Attachment>;
readonly embeds: Embed[];
reply(options: string | MessageReplyOptions): Promise<Message>;
edit(options: string | MessageEditOptions): Promise<Message>;
delete(): Promise<Message>;
react(emoji: EmojiIdentifierResolvable): Promise<MessageReaction>;
}
class EmbedBuilder {
setTitle(title: string): this;
setDescription(description: string): this;
setColor(color: ColorResolvable): this;
addFields(...fields: APIEmbedField[]): this;
}Modern Discord interactions including slash commands, context menus, buttons, modals, and select menus.
class ChatInputCommandInteraction extends CommandInteraction {
readonly commandName: string;
readonly options: CommandInteractionOptionResolver;
reply(options: InteractionReplyOptions): Promise<InteractionResponse>;
editReply(options: InteractionEditReplyOptions): Promise<Message>;
followUp(options: InteractionReplyOptions): Promise<Message>;
}
class ButtonInteraction extends MessageComponentInteraction {
readonly customId: string;
update(options: InteractionUpdateOptions): Promise<InteractionResponse>;
}Message components including action rows, buttons, select menus, modals, and text inputs with builder patterns.
class ActionRowBuilder<ComponentType extends AnyComponentBuilder> {
addComponents(...components: ComponentType[]): this;
setComponents(...components: ComponentType[]): this;
}
class ButtonBuilder {
setCustomId(customId: string): this;
setLabel(label: string): this;
setStyle(style: ButtonStyle): this;
setEmoji(emoji: ComponentEmojiResolvable): this;
}
class ModalBuilder {
setCustomId(customId: string): this;
setTitle(title: string): this;
addComponents(...components: ActionRowBuilder<ModalActionRowComponentBuilder>[]): this;
}Event system for Discord gateway events and collectors for gathering user interactions and messages.
interface ClientEvents {
ready: [client: Client<true>];
messageCreate: [message: Message];
interactionCreate: [interaction: Interaction];
guildCreate: [guild: Guild];
guildMemberAdd: [member: GuildMember];
}
class InteractionCollector extends Collector<Snowflake, Interaction, [Collection<Snowflake, Interaction>]> {
constructor(client: Client, options?: InteractionCollectorOptions);
}
class MessageCollector extends Collector<Snowflake, Message, [Collection<Snowflake, Message>]> {
constructor(channel: TextBasedChannel, options?: MessageCollectorOptions);
}BitField utilities, permission management, constants, formatters, and helper functions for Discord development.
class PermissionsBitField extends BitField<PermissionsString> {
static Flags: typeof PermissionFlagsBits;
has(permission: PermissionResolvable, checkAdmin?: boolean): boolean;
missing(permissions: PermissionResolvable, checkAdmin?: boolean): PermissionsString[];
toArray(): PermissionsString[];
}
class IntentsBitField extends BitField<GatewayIntentsString> {
static Flags: typeof GatewayIntentBits;
}
const Colors: {
Default: 0x000000;
White: 0xffffff;
Aqua: 0x1abc9c;
Green: 0x57f287;
Blue: 0x3498db;
// ... more colors
};Core type definitions used throughout the Discord.js API:
type Snowflake = string;
type ColorResolvable =
| 'Default' | 'White' | 'Aqua' | 'Green' | 'Blue' | 'Yellow' | 'Purple'
| 'LuminousVividPink' | 'Fuchsia' | 'Gold' | 'Orange' | 'Red' | 'Grey'
| 'Navy' | 'DarkAqua' | 'DarkGreen' | 'DarkBlue' | 'DarkPurple' | 'DarkVividPink'
| 'DarkGold' | 'DarkOrange' | 'DarkRed' | 'DarkGrey' | 'DarkerGrey' | 'LightGrey'
| 'DarkNavy' | 'Blurple' | 'Greyple' | 'DarkButNotBlack' | 'NotQuiteBlack'
| number | [number, number, number] | string;
interface ClientOptions {
shards?: number | number[] | 'auto';
shardCount?: number | 'auto';
closeTimeout?: number;
intents: BitFieldResolvable<GatewayIntentsString, number>;
restOptions?: Partial<RESTOptions>;
presence?: PresenceData;
}
interface MessageOptions {
content?: string;
embeds?: (EmbedBuilder | Embed | APIEmbed)[];
files?: (AttachmentBuilder | Attachment | Buffer | string)[];
components?: ActionRowBuilder<MessageActionRowComponentBuilder>[];
}const Events: {
Ready: 'ready';
MessageCreate: 'messageCreate';
InteractionCreate: 'interactionCreate';
GuildCreate: 'guildCreate';
GuildMemberAdd: 'guildMemberAdd';
// ... more events
};
const GatewayIntentBits: {
Guilds: 1 << 0;
GuildMembers: 1 << 1;
GuildModeration: 1 << 2;
GuildMessages: 1 << 9;
MessageContent: 1 << 15;
// ... more intents
};Discord.js provides comprehensive error classes and codes for handling various API and client-side errors.
/**
* Base Discord.js error class
*/
class DiscordjsError extends Error {
constructor(message?: string);
readonly name: 'DiscordjsError';
readonly code: string;
}
/**
* Type-related error class
*/
class DiscordjsTypeError extends TypeError {
constructor(message?: string);
readonly name: 'DiscordjsTypeError';
readonly code: string;
}
/**
* Range-related error class
*/
class DiscordjsRangeError extends RangeError {
constructor(message?: string);
readonly name: 'DiscordjsRangeError';
readonly code: string;
}
/**
* Comprehensive error codes used throughout Discord.js
*/
const DiscordjsErrorCodes: {
// Client errors
ClientInvalidOption: 'ClientInvalidOption';
ClientInvalidProvidedShards: 'ClientInvalidProvidedShards';
ClientMissingIntents: 'ClientMissingIntents';
ClientNotReady: 'ClientNotReady';
// Token errors
TokenInvalid: 'TokenInvalid';
TokenMissing: 'TokenMissing';
ApplicationCommandPermissionsTokenMissing: 'ApplicationCommandPermissionsTokenMissing';
// Sharding errors
ShardingNoShards: 'ShardingNoShards';
ShardingInProcess: 'ShardingInProcess';
ShardingInvalidEvalBroadcast: 'ShardingInvalidEvalBroadcast';
ShardingShardNotFound: 'ShardingShardNotFound';
ShardingAlreadySpawned: 'ShardingAlreadySpawned';
ShardingProcessExists: 'ShardingProcessExists';
ShardingWorkerExists: 'ShardingWorkerExists';
ShardingReadyTimeout: 'ShardingReadyTimeout';
ShardingReadyDisconnected: 'ShardingReadyDisconnected';
ShardingReadyDied: 'ShardingReadyDied';
ShardingNoChildExists: 'ShardingNoChildExists';
ShardingShardMiscalculation: 'ShardingShardMiscalculation';
// BitField errors
BitFieldInvalid: 'BitFieldInvalid';
// Interaction errors
InteractionCollectorError: 'InteractionCollectorError';
InteractionAlreadyReplied: 'InteractionAlreadyReplied';
InteractionNotReplied: 'InteractionNotReplied';
InteractionEphemeralReplied: 'InteractionEphemeralReplied';
// Command interaction errors
CommandInteractionOptionNotFound: 'CommandInteractionOptionNotFound';
CommandInteractionOptionType: 'CommandInteractionOptionType';
CommandInteractionOptionEmpty: 'CommandInteractionOptionEmpty';
CommandInteractionOptionNoSubcommand: 'CommandInteractionOptionNoSubcommand';
CommandInteractionOptionNoSubcommandGroup: 'CommandInteractionOptionNoSubcommandGroup';
CommandInteractionOptionInvalidChannelType: 'CommandInteractionOptionInvalidChannelType';
AutocompleteInteractionOptionNoFocusedOption: 'AutocompleteInteractionOptionNoFocusedOption';
// Modal interaction errors
ModalSubmitInteractionFieldNotFound: 'ModalSubmitInteractionFieldNotFound';
ModalSubmitInteractionFieldType: 'ModalSubmitInteractionFieldType';
// Message errors
MessageBulkDeleteType: 'MessageBulkDeleteType';
MessageContentType: 'MessageContentType';
MessageNonceRequired: 'MessageNonceRequired';
MessageNonceType: 'MessageNonceType';
MessageThreadParent: 'MessageThreadParent';
MessageExistingThread: 'MessageExistingThread';
MessageReferenceMissing: 'MessageReferenceMissing';
// Guild errors
GuildChannelResolve: 'GuildChannelResolve';
GuildVoiceChannelResolve: 'GuildVoiceChannelResolve';
GuildChannelOrphan: 'GuildChannelOrphan';
GuildChannelUnowned: 'GuildChannelUnowned';
GuildOwned: 'GuildOwned';
GuildMembersTimeout: 'GuildMembersTimeout';
GuildUncachedMe: 'GuildUncachedMe';
GuildScheduledEventResolve: 'GuildScheduledEventResolve';
GuildForumMessageRequired: 'GuildForumMessageRequired';
GuildUncachedEntityResolve: 'GuildUncachedEntityResolve';
// Channel errors
ChannelNotCached: 'ChannelNotCached';
StageChannelResolve: 'StageChannelResolve';
ThreadInvitableType: 'ThreadInvitableType';
// Webhook errors
WebhookMessage: 'WebhookMessage';
WebhookTokenUnavailable: 'WebhookTokenUnavailable';
WebhookURLInvalid: 'WebhookURLInvalid';
WebhookApplication: 'WebhookApplication';
// File and resource errors
FileNotFound: 'FileNotFound';
ReqResourceType: 'ReqResourceType';
// Ban errors
BanResolveId: 'BanResolveId';
FetchBanResolveId: 'FetchBanResolveId';
BulkBanUsersOptionEmpty: 'BulkBanUsersOptionEmpty';
// General validation errors
InvalidType: 'InvalidType';
InvalidElement: 'InvalidElement';
InvalidMissingScopes: 'InvalidMissingScopes';
InvalidScopesWithPermissions: 'InvalidScopesWithPermissions';
// Voice errors
VoiceNotStageChannel: 'VoiceNotStageChannel';
VoiceStateNotOwn: 'VoiceStateNotOwn';
VoiceStateInvalidType: 'VoiceStateInvalidType';
// User errors
UserNoDMChannel: 'UserNoDMChannel';
// Misc errors
InviteOptionsMissingChannel: 'InviteOptionsMissingChannel';
EmojiType: 'EmojiType';
FetchOwnerId: 'FetchOwnerId';
PruneDaysType: 'PruneDaysType';
SweepFilterReturn: 'SweepFilterReturn';
EntitlementCreateInvalidOwner: 'EntitlementCreateInvalidOwner';
PollAlreadyExpired: 'PollAlreadyExpired';
NotImplemented: 'NotImplemented';
// Member errors
MemberFetchNonceLength: 'MemberFetchNonceLength';
// Invite errors
InviteResolveCode: 'InviteResolveCode';
InviteNotFound: 'InviteNotFound';
// DM Channel errors
DeleteGroupDMChannel: 'DeleteGroupDMChannel';
FetchGroupDMChannel: 'FetchGroupDMChannel';
// Permission errors
GlobalCommandPermissions: 'GlobalCommandPermissions';
};Usage Examples:
import { DiscordjsError, DiscordjsErrorCodes } from 'discord.js';
// Error handling in async functions
try {
await interaction.reply('Hello!');
await interaction.reply('This will fail!'); // Already replied
} catch (error) {
if (error instanceof DiscordjsError) {
if (error.code === DiscordjsErrorCodes.InteractionAlreadyReplied) {
console.log('Interaction was already replied to');
await interaction.followUp('Follow up message instead');
}
}
}
// Checking for specific client errors
client.on('error', (error) => {
if (error instanceof DiscordjsError) {
switch (error.code) {
case DiscordjsErrorCodes.ClientNotReady:
console.log('Client is not ready yet');
break;
case DiscordjsErrorCodes.TokenInvalid:
console.log('Invalid bot token provided');
break;
default:
console.log('Discord.js error:', error.message);
}
} else {
console.log('Non-Discord.js error:', error);
}
});
// Type-safe error checking
const handleGuildError = (error: unknown) => {
if (error instanceof DiscordjsTypeError &&
error.code === DiscordjsErrorCodes.GuildChannelResolve) {
console.log('Could not resolve guild channel');
}
};