@axrxvm/bdjs
v0.0.4
Published
The ultimate Discord.js wrapper - makes Discord bot development effortless
Maintainers
Readme
BetterDiscordJS
The ultimate Discord.js wrapper that makes Discord bot development effortless for beginners and infinitely powerful for experts.
✨ Features
- Zero Configuration to Start: Working bot in 5 lines of code
- Automatic Everything: Intent detection, command registration, interaction routing
- Universal Compatibility: Single-file, modular, TS, JS, ESM, CommonJS - all supported
- Unified Context System: Single interface for all interactions (slash commands, buttons, modals, etc.)
- Advanced Command System: Slash commands, prefix commands, context menus, subcommands
- Built-in Middleware: Permissions, cooldowns, rate limiting, validation
- Plugin Ecosystem: Database, logging, analytics, i18n, dashboard
- Production Ready: Clustering, sharding, health monitoring, graceful shutdown
- Developer Friendly: Hot reload, debug mode, TypeScript support
🚀 Quick Start
Create a New Bot (Recommended)
Use our interactive CLI to create a fully configured bot in seconds:
npx @axrxvm/bdjs create my-botChoose from:
- JavaScript or TypeScript
- Minimal, Basic, or Advanced templates
- npm, yarn, or pnpm
See CLI Documentation | View Examples
Manual Installation
npm install @axrxvm/bdjs discord.jsYour First Bot
import { BetterBot } from '@axrxvm/bdjs';
const bot = new BetterBot({
token: 'YOUR_BOT_TOKEN'
});
bot.command('ping', (ctx) => {
ctx.reply(`Pong! ${ctx.bot.ping}ms`);
});
bot.start();That's it! You now have a working Discord bot with:
- ✅ Automatic intent detection
- ✅ Slash command support
- ✅ Error handling
- ✅ Rate limiting
- ✅ And much more!
📚 Documentation
Creating Commands
Simple Command
bot.command('hello', (ctx) => {
ctx.reply(`Hello, ${ctx.user.username}!`);
});Advanced Command with Options
bot.command('ban', {
description: 'Ban a member from the server',
slash: true,
permissions: ['BAN_MEMBERS'],
guildOnly: true,
options: [
{
name: 'user',
type: 'USER',
description: 'User to ban',
required: true
},
{
name: 'reason',
type: 'STRING',
description: 'Reason for ban'
}
],
execute: async (ctx) => {
const user = ctx.get('user');
const reason = ctx.get('reason') || 'No reason provided';
await ctx.guild.members.ban(user, { reason });
await ctx.reply(`Banned ${user.tag} for: ${reason}`);
}
});Command with Subcommands
bot.command('config', {
description: 'Configure bot settings',
slash: true,
subcommands: {
prefix: {
description: 'Change bot prefix',
options: [
{ name: 'new_prefix', type: 'STRING', required: true }
],
execute: async (ctx) => {
const prefix = ctx.get('new_prefix');
await ctx.reply(`Prefix changed to: ${prefix}`);
}
},
logs: {
description: 'Set log channel',
options: [
{ name: 'channel', type: 'CHANNEL', required: true }
],
execute: async (ctx) => {
const channel = ctx.get('channel');
await ctx.reply(`Logs will be sent to ${channel}`);
}
}
}
});Events
bot.on('ready', () => {
console.log(`Logged in as ${bot.user.tag}`);
});
bot.on('guildMemberAdd', (member) => {
member.guild.systemChannel?.send(`Welcome ${member}!`);
});
bot.on('messageCreate', async (message) => {
if (message.author.bot) return;
// Handle message...
});Components
Buttons
bot.button('delete', async (ctx) => {
await ctx.message.delete();
await ctx.reply({ content: 'Deleted!', ephemeral: true });
});
// Dynamic buttons with parameters
bot.button('role_{roleId}', async (ctx) => {
const roleId = ctx.params.roleId;
await ctx.member.roles.add(roleId);
await ctx.reply({ content: 'Role added!', ephemeral: true });
});Select Menus
bot.selectMenu('color', async (ctx) => {
const color = ctx.values[0];
await ctx.reply(`You selected ${color}!`);
});Modals
bot.modal('feedback', async (ctx) => {
const rating = ctx.fields.rating;
const comments = ctx.fields.comments;
await ctx.reply('Thanks for your feedback!');
});Builders
Embeds
import { EmbedBuilder } from '@axrxvm/bdjs';
const embed = new EmbedBuilder()
.setTitle('Hello World')
.setDescription('This is an embed')
.setColor('BLUE')
.addField('Field 1', 'Value 1')
.setFooter({ text: 'Footer text' })
.setTimestamp();
await ctx.reply({ embeds: [embed] });Buttons
import { ButtonBuilder, ActionRow } from '@axrxvm/bdjs';
const button = new ButtonBuilder()
.setCustomId('my-button')
.setLabel('Click Me')
.setStyle('PRIMARY')
.setEmoji('👍');
const row = new ActionRow().addComponents(button);
await ctx.reply({
content: 'Click the button!',
components: [row]
});Middleware
import { permissions, cooldown } from '@axrxvm/bdjs/middleware';
// Global middleware
bot.use(permissions({
user: ['MANAGE_MESSAGES'],
message: 'You need Manage Messages permission!'
}));
bot.use(cooldown({
duration: 5000,
message: 'Please wait {time} before using this again!'
}));
// Command-specific middleware
bot.useCommand('ban', async (ctx, next) => {
console.log(`${ctx.user.tag} used ban command`);
await next();
});Plugins
import { DatabasePlugin, LoggerPlugin } from '@axrxvm/bdjs/plugins';
// Database plugin
bot.plugin(new DatabasePlugin({
adapter: 'sqlite',
connection: './bot.db',
models: {
User: {
id: 'string',
balance: 'number',
xp: 'number'
}
}
}));
// Logger plugin
bot.plugin(new LoggerPlugin({
level: 'info',
transports: ['console', 'file']
}));
// Use plugins
await bot.db.users.create({ id: '123', balance: 1000 });
bot.logger.info('Bot started');File-Based Loading
const bot = new BetterBot({
token: process.env.TOKEN,
commands: './commands',
events: './events',
components: './components'
});
// Automatically loads all files from directories
// commands/
// ├── general/
// │ ├── ping.js
// │ └── help.js
// └── moderation/
// ├── ban.js
// └── kick.jsContext System
The Context object is the universal interface for all interactions:
bot.command('example', async (ctx) => {
// Universal properties
ctx.user // User who triggered
ctx.guild // Guild (null in DMs)
ctx.channel // Channel
ctx.bot // BetterBot instance
// Command-specific
ctx.command // Command name
ctx.args // Prefix command args
ctx.options // Slash command options
// Component-specific
ctx.customId // Component custom ID
ctx.params // Parsed params from customId
ctx.values // Select menu values
// Universal methods
await ctx.reply('Hello!')
await ctx.send('Message')
await ctx.edit('Updated')
await ctx.defer()
await ctx.followUp('Follow-up')
// Type-safe getters
const user = ctx.get('user')
const text = ctx.getString('text')
const num = ctx.getInteger('number')
// Permission checks
ctx.userHasPermission('ADMINISTRATOR')
ctx.botHasPermission('SEND_MESSAGES')
});🔧 Configuration
const bot = new BetterBot({
// Authentication
token: process.env.DISCORD_TOKEN,
// Client Options
intents: ['GUILDS', 'GUILD_MESSAGES', 'MESSAGE_CONTENT'],
partials: ['MESSAGE', 'CHANNEL', 'REACTION'],
// Command System
prefix: '!',
mentionPrefix: true,
caseSensitive: false,
// Slash Commands
slashCommands: {
global: true,
autoSync: true,
autoDelete: false
},
// File Loading
commands: './commands',
events: './events',
components: './components',
// Behavior
owners: ['YOUR_USER_ID'],
dev: false,
debug: false,
// Error Handling
handleErrors: true,
errorChannel: 'CHANNEL_ID'
});🌟 Advanced Features
Pagination
import { EmbedPaginator } from '@axrxvm/bdjs';
const pages = [
new EmbedBuilder().setTitle('Page 1'),
new EmbedBuilder().setTitle('Page 2'),
new EmbedBuilder().setTitle('Page 3')
];
const paginator = new EmbedPaginator(ctx, pages, {
time: 300000,
filter: (i) => i.user.id === ctx.user.id
});
await paginator.start();Menus
import { ButtonMenu } from '@axrxvm/bdjs';
const menu = new ButtonMenu(ctx, {
title: 'Choose an action',
buttons: [
{
label: 'Option 1',
customId: 'opt1',
style: 'PRIMARY',
handler: async (i) => {
await i.reply('You chose option 1!');
}
}
]
});
await menu.start();Collectors
// Message collector
const collected = await ctx.awaitMessages({
filter: m => m.author.id === ctx.user.id,
max: 1,
time: 60000
});
// Reaction collector
const reactions = await message.awaitReactions({
filter: (r, u) => r.emoji.name === '👍',
max: 10,
time: 60000
});
// Component collector
const interaction = await message.awaitMessageComponent({
filter: i => i.customId === 'my-button',
time: 60000
});Production Features
// Sharding
const bot = new BetterBot({
shards: 'auto',
shardCount: 'auto',
token: process.env.TOKEN
});
// Clustering
import { ClusterManager } from '@axrxvm/bdjs';
const manager = new ClusterManager('./bot.js', {
totalShards: 'auto',
totalClusters: 4,
token: process.env.TOKEN
});
await manager.spawn();
// Health Monitoring
import { HealthMonitor } from '@axrxvm/bdjs';
const monitor = new HealthMonitor(bot, {
port: 3000,
checks: {
websocket: true,
database: true,
memory: true
}
});
await monitor.start();📖 Examples
Check out the examples directory for complete bot templates:
🟢 Minimal Examples
- JavaScript - Simplest bot (~25 lines)
- TypeScript - Minimal bot with TypeScript
🔵 Basic Examples
- JavaScript - Feature-rich bot with commands, buttons, embeds
- TypeScript - Basic bot with full TypeScript support
🔴 Advanced Examples
- JavaScript - Production-ready with database, logging, middleware
- TypeScript - Advanced bot with type safety
🤝 Contributing
Contributions are welcome! Please read our Contributing Guide first.
📝 License
This project is licensed under the MIT License - see the LICENSE file for details.
🔗 Links
❤️ Support
If you like this project, please give it a ⭐️ on GitHub!
Made with ❤️ by the BetterDiscordJS team
