Quick Start
Create and run your first Discord bot
Get a Discord bot running in minutes with Robo.js and the @robojs/discordjs plugin.
Prerequisites
- Node.js 18 or later.
- A code editor such as VS Code.
- A Discord account.
- A Discord server where you can test your bot (create one for free if needed).
Create a Project
Run the scaffolding command and select the bot kit:
npx create-robo@next my-botFollow the prompts to configure TypeScript and select starter features. The CLI generates a ready-to-run project.
Terminal showing the create-robo CLI wizard with prompts for project name, kit selection highlighting the Bot kit option, TypeScript preference, and feature selection
Project Structure
src/commands/— Slash commands. Each file becomes a command named after the file.src/events/— Gateway event handlers. File names map to Discord event names.src/context/— Context menu commands. Subfoldersuser/andmessage/determine the target type.src/middleware/— Middleware that runs before commands and events.config/plugins/robojs/discordjs.ts— Plugin configuration.
First Command
Create src/commands/ping.ts. Return a string and Robo.js sends it as the bot's reply automatically (this is called Sage mode):
export default () => {
return 'Pong!'
}export default () => {
return 'Pong!'
}For explicit typing:
import type { CommandResult } from '@robojs/discordjs'
export default (): CommandResult => {
return 'Pong!'
}export default () => {
return 'Pong!'
}The plugin registers this as the /ping slash command automatically.
Sage mode (returning a value) is the recommended approach for most commands. Use explicit interaction.reply() when you need fine-grained control over timing, deferrals, or multiple responses.
Discord showing the /ping slash command being used in a text channel, with the bot replying 'Pong!' as a message below the command invocation
First Event
Create src/events/ready.ts. The ready event fires when your bot has successfully connected to Discord:
import { getClient } from '@robojs/discordjs'
export default () => {
const client = getClient()
console.log(`Logged in as ${client.user?.tag}`)
}import { getClient } from '@robojs/discordjs'
export default () => {
const client = getClient()
console.log(`Logged in as ${client.user?.tag}`)
}Set Up Credentials
Before running your bot, you need a bot token and client ID from the Discord Developer Portal.
- Open discord.com/developers/applications and sign in.
- Click New Application, give it a name, and confirm.
- Navigate to the Bot tab and click Reset Token. Copy the token.
- Go to General Information and copy the Application ID.
- Create a
.envfile in your project root:
# .env
DISCORD_TOKEN="your_bot_token"
DISCORD_CLIENT_ID="your_application_id"The bot token is shown only once. Store it immediately. Never commit your .env file to version control.
For faster command updates during development, add your test server ID:
# .env
DISCORD_GUILD_ID="your_test_server_id"See Credentials for more details.
Discord Developer Portal Bot tab showing the Reset Token button and the token field with a partially hidden token value, with the Bot section sidebar navigation visible
Run in Development
Start the development server:
npx robo devWhat you should see: The terminal prints build output followed by your bot's tag (e.g., Logged in as MyBot#1234). If you set DISCORD_GUILD_ID, commands register instantly in your test server.
Changes to commands and events trigger hot reload. The bot reconnects automatically with updated handlers.
Terminal running npx robo dev showing build output, command registration for /ping, and the bot successfully logging in with its Discord tag, followed by a 'ready' message
Troubleshooting
Common issues when running your bot for the first time.
Bot does not start
If you see TOKEN_INVALID or An invalid token was provided, check that your .env file contains a valid DISCORD_TOKEN. The token must be copied from the Bot tab in the Discord Developer Portal, not the client secret or application ID.
# .env
DISCORD_TOKEN="your_bot_token_here"
DISCORD_CLIENT_ID="your_application_id_here"Commands not showing in Discord
Slash commands can take up to an hour to propagate globally. To see them immediately during development, set DISCORD_GUILD_ID in your .env to scope commands to a single server:
# .env
DISCORD_GUILD_ID="your_test_server_id"Then restart with npx robo dev. Guild-scoped commands update instantly.
Bot is online but not responding
- Verify the bot has the
applications.commandsscope in its invite link. Without it, slash commands cannot be registered. - Check that the bot has permission to read and send messages in the channel you are testing in.
- Make sure you are running
npx robo devand the process has not exited with errors.
