Transform messy Discord image spam into beautiful, unified galleries
The zero-friction way to send multiple images in Discord without the clutter
Discord bots that send multiple images create visual chaos:
🤖 Bot: Here are your results!
[Embed 1: Single image with title]
[Embed 2: Single image with title]
[Embed 3: Single image with title]
[Embed 4: Single image with title]
Result: Cluttered chat, repetitive titles, inconsistent spacing, poor mobile experience.
discord-multiimage
creates native-looking galleries that feel like Discord designed them:
🤖 Bot: Here are your results!
[Single unified embed with 4 images in perfect grid layout]
Result: Clean, professional, mobile-friendly image presentations.
npm install discord-multiimage
Ideal for displaying 2–4 images in a single unified layout.
const { mergeImagesInGrid } = require('discord-multiimage');
const { EmbedBuilder } = require('discord.js');
const imageUrls = [
'https://example.com/screenshot1.png',
'https://example.com/screenshot2.png',
'https://example.com/screenshot3.png'
];
const { file, imageUrl } = await mergeImagesInGrid(imageUrls);
const embed = new EmbedBuilder()
.setTitle('Game Screenshots')
.setImage(imageUrl)
.setColor('#5865F2');
await interaction.reply({ embeds: [embed], files: [file] });
Great for scrollable galleries like art portfolios or product shots.
const { buildStackedImageData } = require('discord-multiimage');
const { EmbedBuilder } = require('discord.js');
const { imageUrls, invisibleTitle, groupUrl } = buildStackedImageData([
'https://example.com/art1.jpg',
'https://example.com/art2.jpg',
'https://example.com/art3.jpg'
], {
groupUrl: 'https://portfolio.example.com' // Required for grouping
});
const embeds = imageUrls.map(url =>
new EmbedBuilder()
.setTitle(invisibleTitle) // Invisible but needed for Discord to group (Optional: You can use any title yet it will appear as a link)
.setURL(groupUrl)
.setImage(url)
.setColor('#FF6B6B')
);
await channel.send({ embeds });
Use createMultiImageData()
to let your bot dynamically choose layout style.
const { createMultiImageData } = require('discord-multiimage');
const { EmbedBuilder } = require('discord.js');
const result = await createMultiImageData({
mode: 'grid', // or 'stacked'
imageUrls: ['https://example.com/img1.png', 'https://example.com/img2.png'],
options: {
spacing: 6,
backgroundColor: '#2f3136'
}
});
if (result.file) {
const embed = new EmbedBuilder().setImage(result.imageUrl);
await interaction.reply({ embeds: [embed], files: [result.file] });
} else {
const embeds = result.imageUrls.map(url =>
new EmbedBuilder().setImage(url).setURL(result.groupUrl).setTitle('\u200B')
);
await channel.send({ embeds });
}
2 Images | 3 Images | 4 Images |
---|---|---|
Side-by-side (16:9 ratio) |
Large + Stack (4:3 ratio) |
Perfect Grid (1:1 ratio) |
|
|
|
❌ Without discord-multiimage | ✅ With discord-multiimage |
---|---|
|
|
const { file, imageUrl } = await mergeImagesInGrid(urls, {
spacing: 4, // Pixels between images (default: 2)
maxWidth: 800, // Maximum canvas width (default: 600)
backgroundColor: '#36393f', // Canvas background color
cornerRadius: 8 // Rounded corners for images
});
const { imageUrls, invisibleTitle, groupUrl } = buildStackedImageData(urls, {
groupUrl: 'https://your-site.com/gallery', // Required for grouping
titleText: '\u200B' // Custom invisible character (default: zero-width space)
});
// Show match highlights in one clean embed
const highlights = await mergeImagesInGrid([
killcam1, killcam2, scoreboard, playerStats
]);
// Create scrollable art galleries
const gallery = buildStackedImageData(artworkUrls, {
groupUrl: 'https://artist.portfolio.com'
});
// Combine multiple chart screenshots
const dashboard = await mergeImagesInGrid([
salesChart, trafficChart, conversionChart
]);
// Product image galleries
const productGallery = buildStackedImageData([
mainPhoto, sideView, detailShot, packagingPhoto
]);
Scenario | Recommended Mode | Why |
---|---|---|
Screenshots to compare side-by-side | Grid | Visual comparison is easier |
Art portfolio or photo gallery | Stacked | Users want to focus on each image |
Dashboard with multiple charts | Grid | Overview of all metrics at once |
Step-by-step tutorial images | Stacked | Sequential viewing preferred |
Before/after comparisons | Grid | Direct visual comparison |
Large collection (5+ images) | Stacked | Grid limited to 4 images max |
- ✅ Works with Discord.js v14+
⚠️ Requires Node.js ≥ 16.9- 🖼️ Uses skia-canvas — make sure your environment supports native modules
-
Core:
discord.js
v14+ -
Image Processing:
skia-canvas
(faster than node-canvas) - Zero bloat: No unnecessary dependencies
- Automatic resizing to fit Discord's embed limits
- Smart aspect ratio preservation
- WebP optimization for smaller file sizes
- Cross-platform canvas rendering
- ✅ Mobile optimized - perfect scrolling and zoom
- ✅ Desktop native - looks like built-in Discord features
- ✅ Embed limits - respects Discord's 25MB file size limits
- ✅ Rate limiting - works with standard Discord.js rate limiting
Problem: Embeds appear separately instead of grouped.
// Missing required URL
.setURL(groupUrl) // ← This is required for grouping!
Problem: Large images taking too long to process.
// Optimize with smaller max width
await mergeImagesInGrid(urls, { maxWidth: 400 });
Problem: Images don't scale properly on small screens.
// Discord handles this automatically with our layouts!
// No additional code needed - it just works ✨
We love contributions! Here's how to get started:
- Fork the repository
-
Clone your fork:
git clone https://github.com/sajidurdev/discord-multiimage.git
-
Install dependencies:
npm install
-
Create a feature branch:
git checkout -b amazing-feature
- Make your changes and add tests
- Submit a pull request
git clone https://github.com/sajidurdev/discord-multiimage.git
cd discord-multiimage
npm install
npm test
MIT © sajidurdev
Free to use in any project - commercial or open source. Attribution appreciated but not required.
Made with ❤️ for the Discord community
📚 Usage Guide • 🐛 Report Bug • 💡 Request Feature • 💬 Discord Server
⭐ Star this repo if it helped you build better Discord bots! ⭐