NewSchokr 13 is here. A whole new UI, seven locations, snapshots and more. Read more →

How to make a discord.js bot from scratch (v14)

Set up a discord.js v14 project, create a Client with GatewayIntentBits, log in with a token from .env and reply to your first command.

Updated · 2 min read

A minimal discord.js v14 bot is one package.json and one index.js: create a Client with the intents you need, listen for events, and call client.login() with your token. This guide builds that on your own computer so you can test before deploying to Schokr.

Prerequisites

1. Create the project

mkdir my-bot
cd my-bot
npm init -y
npm install discord.js dotenv

2. Add your token to .env

Create a file named .env next to your code:

DISCORD_TOKEN=paste-your-token-here

If you use git, add .env and node_modules to .gitignore so the token never gets committed.

3. Write index.js

require('dotenv').config();
const { Client, Events, GatewayIntentBits } = require('discord.js');

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
  ],
});

client.once(Events.ClientReady, (readyClient) => {
  console.log(`Logged in as ${readyClient.user.tag}`);
});

client.on(Events.MessageCreate, async (message) => {
  if (message.author.bot) return;
  if (message.content === '!ping') {
    await message.reply(`Pong! ${client.ws.ping} ms`);
  }
});

client.on(Events.Error, (error) => console.error('Client error:', error));

client.login(process.env.DISCORD_TOKEN);

What the intents do

IntentNeeded for
GuildsBasic server, channel and role data. Almost every bot needs it.
GuildMessagesReceiving messageCreate events in server channels.
MessageContentReading the text of messages. Privileged: must also be enabled in the Developer Portal.

If you only use slash commands you can drop GuildMessages and MessageContent. Slash commands are the recommended approach for new bots; see slash commands in discord.js.

4. Add a start script

In package.json, add a start script and make sure main points at your file:

{
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  }
}

5. Enable Message Content and run it

  1. In the Developer Portal, on the Bot page, turn on Message Content Intent. Without it, login fails with "Used disallowed intents" (see privileged intents).
  2. Run npm start.
  3. You should see Logged in as YourBot#1234. Type !ping in a channel the bot can see.

Deploy it

Once it works locally, follow deploy a discord.js bot to Schokr to run it 24/7.

Common mistakes

  • Requiring Intents instead of GatewayIntentBits: that's v13 syntax and fails in v14.
  • message.content is empty: the MessageContent intent is missing in code or in the portal.
  • Using the client secret instead of the bot token: the OAuth2 client secret is not the token. Get the token from the Bot page.