To make a Discord bot, create an app in the Discord Developer Portal, copy its bot token, add the bot to your server with an install link, then write a small program with a library such as discord.js (JavaScript) or discord.py (Python) and run it. The bot is online whenever that program is running. The whole first version, a bot that answers a /ping slash command, takes about 30 lines of code.
This guide walks through every step for a complete beginner, with working code for both languages, and ends with what you need to know about keeping a bot online.
What you need
- A Discord account and a server where you have the Manage Server permission (your own test server is easiest). Discord only lets owners and members with Manage Server add apps to a server.
- One programming language installed:
- JavaScript: Node.js. The current discord.js release (14.27.0) requires Node.js 18 or newer; install a current LTS version.
- Python: Python 3. The current discord.py release (2.7.1) requires Python 3.8 or newer; a recent 3.x version is best.
- A code editor, such as VS Code.
Creating the application in the Developer Portal does not cost anything. The only cost that can come up later is hosting, covered at the end.
Step 1: Create the app in the Developer Portal
- Go to the Discord Developer Portal (discord.com/developers/applications) and sign in.
- Click Create App (or New Application), give it a name, and confirm.
- Note the Application ID on the app's main page. You will not need it for this guide, but it identifies your bot.
Step 2: Get the bot token
- Open the Bot page in your app's settings.
- Under Token, click Reset Token and copy the token it shows.
- Store it somewhere safe, such as a password manager.
Treat the token like a password. Discord's docs warn that the token carries your app's permissions, so you should never share it or commit it to version control. You also cannot view it again later; if you lose it or it leaks, reset it and update your code.
Step 3: Decide on intents
Intents tell Discord which events your bot wants to receive. Three are "privileged" and are switched on from the Privileged Gateway Intents section of the Bot page:
| Privileged intent | What it gives you |
|---|---|
| Presence | Members' online status and activities |
| Server Members | The full member list and join or leave events |
| Message Content | The text, embeds, attachments, components and polls of messages |
For this guide you need none of them. Slash commands work without Message Content. Without that intent, message text arrives empty except in messages your bot sends, DMs with your bot, messages that mention your bot, and messages where someone uses one of your bot's message context-menu commands.
Only turn on what your bot genuinely needs. While your app reaches fewer than 10,000 users you can enable privileged intents yourself; past that, Discord asks you to apply and explain your use case.
Step 4: Invite the bot to your server
- Open the Installation page in your app's settings.
- Under Install Link, choose Discord Provided Link.
- Under Default Install Settings, in Guild Install, add the
applications.commandsandbotscopes. - A Permissions list appears once
botis selected. For this guide, Send Messages is enough. - Save, copy the install link, open it in your browser, pick your test server and authorize.
Your bot now appears in the server's member list, offline. It comes online when you run the code below. For help choosing permissions for a real bot, see what permissions to give a Discord bot.
Step 5: Get your server ID
The code below registers the /ping command on one server, where commands show up straight away, which is ideal while you test. To copy the server's ID, turn on Developer Mode (User Settings, then Advanced), then right-click your server's icon and choose Copy Server ID.
Step 6a: Write the bot in JavaScript (discord.js)
In a new folder, run:
npm init -y
npm install discord.js
Create a file named .env in that folder (and never share or upload it):
DISCORD_TOKEN=paste-your-token-here
GUILD_ID=paste-your-server-id-here
Create index.js:
const { Client, Events, GatewayIntentBits } = require('discord.js');
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.once(Events.ClientReady, async (readyClient) => {
console.log(`Logged in as ${readyClient.user.tag}`);
const guild = await readyClient.guilds.fetch(process.env.GUILD_ID);
await guild.commands.set([
{ name: 'ping', description: 'Check that the bot is alive' },
]);
});
client.on(Events.InteractionCreate, async (interaction) => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === 'ping') {
await interaction.reply('Pong!');
}
});
client.login(process.env.DISCORD_TOKEN);
Run it with Node's built-in env-file support (Node.js 20.6 or newer):
node --env-file=.env index.js
Step 6b: Or write it in Python (discord.py)
Install the library:
pip install -U discord.py
Create bot.py:
import os
import discord
from discord import app_commands
GUILD = discord.Object(id=int(os.environ["GUILD_ID"]))
class MyClient(discord.Client):
def __init__(self):
super().__init__(intents=discord.Intents.default())
self.tree = app_commands.CommandTree(self)
async def setup_hook(self):
self.tree.copy_global_to(guild=GUILD)
await self.tree.sync(guild=GUILD)
client = MyClient()
@client.tree.command(description="Check that the bot is alive")
async def ping(interaction: discord.Interaction):
await interaction.response.send_message("Pong!")
client.run(os.environ["DISCORD_TOKEN"])
Set DISCORD_TOKEN and GUILD_ID as environment variables in your terminal before running python bot.py, or load them from a .env file with a package such as python-dotenv. discord.Intents.default() leaves the privileged intents off, which is what you want here.
Step 7: Test it
With the program running, go to your server and type /ping. Your bot's command appears in the list; send it and the bot replies "Pong!". If the bot shows offline, the program is not running or the token is wrong. If the command does not appear, check that the install link included the applications.commands scope.
Step 8: Keep it online (hosting basics)
A bot is only online while its program runs. Close the terminal or turn off your computer and it goes offline. To keep it running all the time you have three broad options:
| Option | Good for | Watch out for |
|---|---|---|
| A computer you leave on (an old laptop, a Raspberry Pi) | Learning, small private bots | Power cuts, home internet drops, updates restarting the machine |
| A virtual private server (VPS) | Full control, any language | You maintain the server, updates and restarts yourself |
| An app hosting platform | Pushing code and letting the platform run it | Free plans can sleep or limit running hours; read the plan details |
Whichever you choose:
- Put the token in the host's environment variables or secrets settings, never in the code you upload.
- Use a process manager so the bot restarts if it crashes. For Node.js, pm2 is a common choice; on Linux, a systemd service works for any language.
- Log errors somewhere you can read them, so you know why it stopped.
Where to go from here
- Add more slash commands, with options such as a user or a number.
- Send embeds instead of plain text. Both libraries have builders for them (EmbedBuilder in discord.js, discord.Embed in discord.py).
- If your bot grows past 100 servers, Discord requires you to verify the app, which includes the developer team owner confirming their identity through Stripe.
If what you actually need is common server features, such as moderation, XP, tickets or welcome messages, you may not need to build anything: an existing bot like PeakBot already covers those (see its features). Our post on whether it is hard to make a Discord bot compares coding your own with no-code and ready-made options.
Frequently asked questions
Is it free to make a Discord bot?
Yes. Creating an application and a bot in the Discord Developer Portal costs nothing, and discord.js and discord.py are free, open-source libraries. Hosting is the only part that can cost money, and you can run a bot on your own computer while you learn.
Should I use Python or JavaScript for a Discord bot?
Use the language you already know. If you know neither, both libraries are mature, free and well documented, so pick the language you would rather learn. JavaScript is also useful if you later want to build a website or dashboard for your bot.
Why can't my bot read messages?
Reading the text of normal messages needs the Message Content privileged intent, enabled on the Bot page in the Developer Portal and requested in your code. Without it, message text is empty except in DMs with your bot, messages that mention it, and its own messages. Many bots avoid needing it by using slash commands.
Why doesn't my slash command show up?
Check that the bot was invited with the applications.commands scope, that your program ran without errors and registered the command, and that you registered it on the same server you are testing in.
Can I make a Discord bot without coding?
Yes, with no-code builders. Our guide to creating a Discord bot without coding compares the main options and their limits.
