Home › Discord bots › Discord bot (discord.js) Cursor rules
Discord bot (discord.js) Cursor rules
Cursor rules for Discord bots with discord.js: slash command handlers, minimal intents, deferring within 3 seconds, permissions, rate limits, and secrets.
CursorDiscord bots
How to use
Save this as .cursor/rules/discord-bot.mdc in your repository root, commit it, and your agent will pick it up automatically. Edit the commands to match your project.
Note: Review and test before use. Provided as is, without warranty. See Terms.
.cursor/rules/discord-bot.mdcDownload ---
description: discord.js bot conventions
globs: ["src/**/*.{ts,js}"]
alwaysApply: false
---
# Discord bot (discord.js)
## Commands
`npm run dev` · `npm run build` · `npm test` · register slash commands: `npm run deploy-commands` (guild-scoped for development, global only for releases).
## Structure
- One file per slash command in `src/commands/` exporting `data` (a `SlashCommandBuilder`) and `execute(interaction)`; one file per event in `src/events/`. A loader registers them; no giant `switch` in the entry file.
- Command registration is a separate script using the REST API, never run on every bot start.
## Rules
- Request only the gateway intents the features need (`Guilds` by default). Privileged intents (`MessageContent`, `GuildMembers`, `GuildPresences`) need a written reason in the README and must be enabled in the developer portal.
- Interactions must be acknowledged within 3 seconds: call `interaction.deferReply()` (ephemeral where appropriate) before any slow work, then `editReply`. Use `followUp` for extra messages.
- Ephemeral replies for errors and user-specific info. Never echo tokens, IDs of other users' private data or stack traces into channels.
- Check permissions explicitly: `setDefaultMemberPermissions` on admin commands plus a runtime check of `interaction.memberPermissions` and the bot's own permissions before acting.
- Validate options from `interaction.options.get*()`; treat all user text as untrusted. Disable mass mentions with `allowedMentions: { parse: [] }` when echoing user input.
- Rate limits: discord.js queues REST calls; don't loop bulk actions without batching. Use bulk endpoints where they exist.
- Wrap every `execute` in try/catch: log the error with the command name and reply (or editReply) with a friendly ephemeral message.
- Long-lived state goes in a database, not in-memory maps, so restarts and shards don't lose it.
- Token and IDs from environment variables (`DISCORD_TOKEN`, `CLIENT_ID`); `.env` is gitignored. Never commit or log the token.
## Done when
Typecheck and tests pass, commands deployed to the dev guild, and the changed command works there.