A Discord embed does what a plain-text message can't: it turns information into a tidy card with a colored side bar, a title, fields, a thumbnail and a footer. When your bot answers a command with this polished card instead of raw text, everyone on the server instantly finds the message more readable and professional. In this guide we'll build up color, fields and thumbnail usage step by step with the EmbedBuilder class from discord.js v14.
What is an embed, and when should you use one?
An embed is a structured block that Discord renders inside a message. The preview card that pops up automatically when you share a link is also an embed; bots simply build that card by hand. Good places to use embeds:
- Command output: data that splits into fields, such as a user profile, server stats or weather.
- Logs and notifications: using color to signal "success / warning / error".
- Announcements: eye-catching messages with a title, description and image.
For one-line answers an embed is overkill; plain text reads faster. Reach for an embed when the information genuinely benefits from structure.
Your first embed with EmbedBuilder
In discord.js v14, embeds are built through EmbedBuilder using chained methods. A basic example:
const { EmbedBuilder } = require('discord.js');
const embed = new EmbedBuilder()
.setColor(0x5865F2)
.setTitle('Server Info')
.setDescription('Below is a summary of the server.')
.setTimestamp();
await interaction.reply({ embeds: [embed] });
Note that the embed is sent inside the message's embeds array, not as a raw string. A single message can hold up to 10 embeds, but one is usually plenty.
Color: express your brand with a single tone
Color is the vertical bar on the left edge of the embed, and it sets the message's "tone" at a glance. setColor accepts several formats:
const { Colors } = require('discord.js');
embed.setColor(0x57F287); // hex number (green)
embed.setColor('#ED4245'); // hex string (red)
embed.setColor([88, 101, 242]); // RGB array (Discord blurple)
embed.setColor(Colors.Gold); // built-in color constant
embed.setColor('Random'); // a random color each time
A handy convention: green = success, yellow = warning, red = error, brand blurple = neutral info. Collecting your colors in a single object keeps things consistent:
const COLORS = { success: 0x57F287, warn: 0xFEE75C, error: 0xED4245 };
embed.setColor(COLORS.success);
Fields: split data into neat columns
Fields are the most powerful part of an embed: each one carries a name (title) and a value. Set inline: true and the fields line up side by side; Discord shows at most three inline fields per row.
embed.addFields(
{ name: 'Members', value: '1,248', inline: true },
{ name: 'Channels', value: '37', inline: true },
{ name: 'Created', value: 'Mar 12, 2021', inline: true },
{ name: 'About', value: 'The community\'s main server.', inline: false },
);
If you want to align things with an empty cell, use an invisible heading:
embed.addFields({ name: '', value: '', inline: true });
The character above is a zero-width space; since Discord rejects an empty name or value, this is the trick people use.
Thumbnail, image, author and footer
The remaining pieces round out the embed. The thumbnail is the small square image in the top right; the image is the large picture at the bottom. The author shows a small title plus icon at the very top, while the footer offers a small note at the very bottom.
embed
.setAuthor({
name: 'Aslain Bot',
iconURL: 'https://example.com/bot.png',
url: 'https://aslain.dev',
})
.setThumbnail('https://example.com/avatar.png')
.setImage('https://example.com/banner.png')
.setFooter({ text: 'aslain.dev', iconURL: 'https://example.com/icon.png' });
For images you can use an external URL, or reference a file you upload with the bot through the attachment:// scheme:
const { AttachmentBuilder } = require('discord.js');
const file = new AttachmentBuilder('./avatar.png', { name: 'avatar.png' });
embed.setThumbnail('attachment://avatar.png');
await interaction.reply({ embeds: [embed], files: [file] });
Watch the limits
Discord enforces strict character limits on embeds. Exceed them and the API rejects the message, so the bot fails silently. The most important ones:
- title: 256 characters
- description: 4096 characters
- field count: up to 25 (name 256, value 1024 characters)
- footer.text: 2048, author.name: 256 characters
- Combined total of all text in a single embed: 6000 characters
If you put user input into an embed, make it safe by truncating values with something like slice(0, 1024); otherwise one long message can break the whole reply.
Frequently Asked Questions
Why EmbedBuilder instead of MessageEmbed?
In discord.js v13 the class was called MessageEmbed. v14 renamed it to EmbedBuilder and removed addField (singular) in favor of addFields (plural). Always use the v14 names in new projects; copying older examples verbatim will throw errors.
Can I let users pick the embed color?
Yes. Add an option to your slash command and pass the incoming hex value to setColor. Just validate the input first: an invalid value throws, so add a check like /^#?[0-9a-f]{6}$/i.
Do embeds look the same for everyone?
The structure is identical, but there are small visual differences between light/dark themes and mobile/desktop. It's worth testing on mobile that your thumbnail and image sizes don't overflow.
Want your bot's messages to match your brand? From embed design to command architecture, we can build your Discord bot together. Get in touch to talk about your project.