Last Updated: November 21, 2025
Setup & Installation
npm install discord.js
Install Discord.js library
const { Client, GatewayIntentBits } = require('discord.js');
Import Discord.js (v14+)
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
Create bot client with intents
client.login('YOUR_BOT_TOKEN');
Log in bot with token
client.on('ready', () => {});
Bot ready event
Gateway Intents
GatewayIntentBits.Guilds
Server events (required)
GatewayIntentBits.GuildMessages
Message events in servers
GatewayIntentBits.MessageContent
Access message content (privileged)
GatewayIntentBits.GuildMembers
Member events (privileged)
GatewayIntentBits.GuildPresences
Presence updates (privileged)
GatewayIntentBits.DirectMessages
DM events
GatewayIntentBits.GuildVoiceStates
Voice state changes
Message Events
client.on('messageCreate', message => {});
Listen for new messages
if (message.author.bot) return;
Ignore bot messages
message.content
Message text content
message.author
Message author (User object)
message.channel
Channel where message sent
message.guild
Server (guild) object
message.reply('Hello!');
Reply to message
message.channel.send('Message');
Send message to channel
message.delete();
Delete message
message.react('👍');
Add reaction to message
Slash Commands
const { SlashCommandBuilder } = require('discord.js');
Import command builder
new SlashCommandBuilder().setName('ping').setDescription('Replies with Pong!')
Create slash command
.addStringOption(option => option.setName('input').setDescription('text'))
Add string option
.addIntegerOption(...)
Add integer option
.addBooleanOption(...)
Add boolean option
.addUserOption(...)
Add user selection option
.addChannelOption(...)
Add channel selection option
.addRoleOption(...)
Add role selection option
client.on('interactionCreate', async interaction => {});
Handle slash command interactions
interaction.reply('Response');
Reply to slash command
interaction.deferReply();
Defer reply (thinking... state)
interaction.editReply('Updated');
Edit deferred reply
Embeds
const { EmbedBuilder } = require('discord.js');
Import embed builder
new EmbedBuilder().setTitle('Title')
Set embed title
.setDescription('Text')
Set embed description
.setColor(0x0099FF)
Set embed color (hex)
.addFields({ name: 'Field', value: 'Value' })
Add fields to embed
.setThumbnail(url)
Set small image (top-right)
.setImage(url)
Set large image (bottom)
.setFooter({ text: 'Footer' })
Set embed footer
.setTimestamp()
Add current timestamp
channel.send({ embeds: [embed] });
Send embed message
Permissions
PermissionFlagsBits.Administrator
All permissions
PermissionFlagsBits.ManageMessages
Delete/pin messages
PermissionFlagsBits.ManageChannels
Manage channels
PermissionFlagsBits.ManageRoles
Manage roles
PermissionFlagsBits.KickMembers
Kick members
PermissionFlagsBits.BanMembers
Ban members
member.permissions.has(PermissionFlagsBits.Administrator)
Check if user has permission
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
Restrict slash command to permission
Buttons & Components
const { ButtonBuilder, ButtonStyle, ActionRowBuilder } = require('discord.js');
Import button components
new ButtonBuilder().setCustomId('id').setLabel('Click').setStyle(ButtonStyle.Primary)
Create button
ButtonStyle.Primary
Blue button
ButtonStyle.Success
Green button
ButtonStyle.Danger
Red button
ButtonStyle.Link
URL button (requires .setURL())
new ActionRowBuilder().addComponents(button1, button2)
Create row of components
channel.send({ content: 'Text', components: [row] });
Send message with buttons
if (interaction.isButton())
Check if interaction is button
interaction.customId
Get button custom ID
Moderation
member.kick(reason);
Kick member from server
member.ban({ reason: 'reason' });
Ban member
guild.bans.remove(userId);
Unban user
member.timeout(duration, reason);
Timeout member (mute)
member.roles.add(roleId);
Add role to member
member.roles.remove(roleId);
Remove role from member
channel.bulkDelete(amount);
Delete multiple messages (max 100)
Voice
npm install @discordjs/voice
Install voice library
const { joinVoiceChannel } = require('@discordjs/voice');
Import voice functions
joinVoiceChannel({ channelId, guildId, adapterCreator })
Join voice channel
connection.destroy();
Leave voice channel
Event Handling
client.on('guildMemberAdd', member => {});
New member joins server
client.on('guildMemberRemove', member => {});
Member leaves server
client.on('messageDelete', message => {});
Message deleted
client.on('messageUpdate', (oldMsg, newMsg) => {});
Message edited
client.on('voiceStateUpdate', (oldState, newState) => {});
Voice state changed
Common Methods
guild.members.fetch(userId)
Get member by ID
guild.channels.cache.get(channelId)
Get channel by ID
guild.roles.cache.find(role => role.name === 'Admin')
Find role by name
user.send('DM message')
Send direct message to user
channel.messages.fetch({ limit: 100 })
Fetch recent messages
💡 Pro Tip:
Always enable required Gateway Intents in the Discord Developer Portal. Use slash commands for modern Discord bots - they're the recommended approach over prefix commands!