Discord bot source
- TypeScript 97.3%
- JavaScript 2.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| config | ||
| logs | ||
| src | ||
| .editorconfig | ||
| .env.example | ||
| .gitignore | ||
| .prettierrc | ||
| agmh.txt | ||
| ecosystem.config.cjs | ||
| eslint.config.mjs | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
Discord Bot Template
A reliable TypeScript foundation for Discord bots using Discord.js, dotenv, JSON configuration, automatic command registration, event loading, connection management, and PM2 process supervision.
Stack
- TypeScript
- Discord.js
- dotenv
- PM2
- ESLint and Prettier
Project Structure
config/
bot.config.json Runtime bot settings and protections
bot.config.schema.json JSON schema for editor validation
logs/
.gitkeep Keeps the log directory in git
src/
commands/
admin/ Owner-only and critical commands
utility/ General commands
config/ Environment and JSON config loading
core/ Bot runtime, command/event registries, guards, PM2-safe connection logic
events/ Discord event handlers
logging/ Console logger used by PM2 log files
types/ Shared bot contracts
utils/ Small runtime utilities
ecosystem.config.cjs PM2 process configuration
Setup
-
Install dependencies:
npm install -
Create your environment file:
cp .env.example .env -
Set
DISCORD_TOKENin.env. -
Edit
config/bot.config.json:applicationId: Discord application/client ID.security.ownerUserId: the only user allowed to run owner-only and critical commands.security.authorizedGuildIds: servers allowed to use the bot.client.intents: Discord gateway intents needed by your commands/events.
-
Build:
npm run build -
Start locally:
npm start
Development
Run with live reload:
npm run dev
Register commands without starting the bot:
npm run register
Check quality:
npm run lint
npm run typecheck
PM2
Start with PM2:
npm run pm2:start
Reload after changes:
npm run pm2:reload
Stop:
npm run pm2:stop
The PM2 ecosystem file uses:
- process name
discord-bot ./dist/index.jsscript- project root as
cwd - 1 instance
- fork mode
- autorestart enabled
- watch disabled
1Gmemory restart limit- separate output and error logs in
logs/ - log date format
YYYY-MM-DD HH:mm:ss Z - default
NODE_ENV=production
Built-In Protections
The JSON config controls core safety rules:
- authorized guild allowlist
- automatic leave from unauthorized guilds
- direct-message command rejection
- owner-only critical commands
- per-user command rate limiting
- command registration scope, either guild or global
The starter commands include:
/ping: latency and uptime check/health: owner-only runtime health check/reload-commands: owner-only command reload and registration
Adding Commands
Create a file under src/commands/<category>/<name>.ts and export a BotCommand:
import { SlashCommandBuilder } from 'discord.js';
import type { BotCommand } from '../../types/command';
const command: BotCommand = {
data: new SlashCommandBuilder().setName('example').setDescription('Example command.'),
async execute({ interaction }) {
await interaction.reply('Done.');
},
};
export default command;
Use ownerOnly: true or critical: true for sensitive actions.
Adding Events
Create a file under src/events/<event>.ts and export a BotEvent:
import { Events } from 'discord.js';
import type { BotEvent } from '../types/event';
const event: BotEvent<Events.ClientReady> = {
name: Events.ClientReady,
once: true,
execute(context, client) {
context.logger.info(`Ready as ${client.user.tag}.`);
},
};
export default event;