|

Build a Discord Bot With Node.js and Host It 24/7

Learning to build a Discord bot with Node.js is one of the most rewarding first projects for any JavaScript developer. Your bot can answer slash commands, welcome new members, and run chores around the clock. However, many tutorials end at “it works on my laptop,” and the bot goes offline the moment you close the terminal. This guide closes that gap.

First, you will create an application in the Discord Developer Portal and invite it to a test server. Next, you will write a bot with discord.js, the most popular Node.js library for the Discord API. After that, you will prepare the code for production and deploy it so it stays online 24 hours a day. Along the way, you will see exactly which commands to type and why each step matters.

This tutorial reflects the tools available in October 2026. It uses discord.js 14 (the 14.27 release at the time of writing), Node.js 24 LTS, and slash commands, which are the modern way for users to talk to bots. If you can write a basic JavaScript function, you can follow every step.

What You Will Build in This Discord Bot With Node.js Tutorial

Before writing code, it helps to see the finished product. Your Discord bot with Node.js will respond to three slash commands. The first, /ping, replies with the bot’s latency. The second, /roll, rolls a die with a number of sides you choose. The third, /serverinfo, posts a tidy embed with details about the server where someone runs it.

These commands are simple on purpose. Together, they teach every pattern you need for larger projects: command files, option handling, embeds, error handling, and a clean project layout. Once you understand them, adding a moderation tool or an AI chat feature becomes a matter of repeating the same pattern.

The stack is small. You need Node.js as the runtime, discord.js as the library, and a handful of tools for hosting. If you want a refresher on how these pieces fit together, our guide to what a tech stack is explains the idea in plain language.

How a Discord Bot Actually Works

A bot is not a website. Instead, it opens a long-lived WebSocket connection to Discord’s Gateway and keeps that connection open. Discord pushes events down the connection, such as a user running a slash command. Your code reacts to each event and sends a reply through Discord’s REST API.

This design explains why hosting a Discord bot with Node.js differs from hosting a web app. A website waits for visitors and can sleep between requests. A bot, by contrast, must stay connected all the time, or it appears offline. Keep that difference in mind, because it drives every hosting decision later in this guide.

What You Need Before You Start

Gather these tools first, and the rest of the tutorial will go smoothly:

  • Node.js 24 LTS. Download it from the official Node.js website. Node 24 receives support until April 2028, so it is a safe choice. Node.js 26 also becomes an LTS release this month, and it works too.
  • A code editor. Visual Studio Code is free and popular, but any editor will do.
  • A Discord account and a test server. Create a fresh server just for testing, so you never break a real community.
  • A GitHub account. You will push your code there before you deploy it.
  • A terminal. Windows Terminal, macOS Terminal, or any Linux shell works.

Next, confirm your Node.js version by running this command:

bash

node --version

If the output starts with v24 or higher, you are ready. Otherwise, install the latest LTS version and check again.

Finally, turn on Developer Mode in Discord. Open User Settings, go to Advanced, and switch on Developer Mode. This setting lets you right-click a server and copy its ID, which you will need shortly.

Step 1: Create Your Application in the Discord Developer Portal

Every Discord bot starts as an application. The Discord Developer Portal is where you create it, configure it, and grab the secret token your code uses to log in.

Create the Application

Open the portal and sign in. Click New Application, enter a name, accept the terms, and click Create. You land on the General Information page. Copy the Application ID from this page, because it becomes your CLIENT_ID later.

Add the Bot and Copy Its Token

Now open the Bot tab in the left menu. Every new application already includes a bot user. Click Reset Token, confirm your password if Discord asks, and copy the token that appears.

Treat this token like a password. Anyone who holds it can control your bot. Discord shows the token only once, so store it somewhere safe right away. If you ever lose it or leak it, simply reset it and update your code.

Understand Gateway Intents

On the same Bot page, you will see a section called Privileged Gateway Intents. Intents tell Discord which categories of events your bot wants to receive. Three of them are privileged: Presence, Server Members, and Message Content.

Good news for this project: slash commands arrive as interactions, so you do not need any privileged intent. Leave all three switches off. Your bot needs only the standard Guilds intent, which requires no toggle.

Keep in mind that privileged intents come with rules. Once your bot grows to 100 servers, Discord requires verification and approval before you can use them. Starting without them keeps your Discord bot with Node.js simple and compliant from day one.

Step 2: Invite the Bot to Your Server

A bot cannot do anything until it joins a server. Fortunately, the invite link takes less than a minute to build.

  1. In the Developer Portal, open OAuth2 and find the URL Generator.
  2. Under Scopes, tick bot and applications.commands.
  3. Under Bot Permissions, tick Send Messages and Embed Links. Grant only what you need.
  4. Copy the generated URL at the bottom, paste it into your browser, and choose your test server.

You need the Manage Server permission on that server to add a bot. After you authorize it, the bot appears in your member list. Do not worry that it shows as offline. It stays offline until your code connects, which happens in a few steps.

Step 3: Set Up the Project for Your Discord Bot With Node.js

Now for the fun part. Create a project folder, initialize it, and install discord.js:

bash

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

Then create the following structure. A clear layout keeps a Discord bot with Node.js easy to extend as you add commands.

my-discord-bot/
├── src/
│   ├── commands/
│   │   ├── ping.js
│   │   ├── roll.js
│   │   └── serverinfo.js
│   ├── deploy-commands.js
│   └── index.js
├── .env
├── .gitignore
└── package.json

Store Secrets in a .env File

Create a file named .env in the project root and add your three values:

DISCORD_TOKEN=paste-your-bot-token-here
CLIENT_ID=paste-your-application-id-here
GUILD_ID=paste-your-test-server-id-here

To find the server ID, right-click your test server in Discord and choose Copy Server ID. Then create a .gitignore file so secrets and dependencies never reach GitHub:

node_modules
.env

Add npm Scripts

Open package.json and replace the scripts section. Modern Node.js can read .env files natively, so you do not need an extra package for local development.

json

"scripts": {
  "start": "node src/index.js",
  "dev": "node --watch --env-file=.env src/index.js",
  "deploy": "node --env-file=.env src/deploy-commands.js"
}

The dev script restarts the bot automatically whenever you save a file. Meanwhile, the start script runs the bot normally, and production hosts will use it. Since hosts supply environment variables themselves, start does not read a .env file.

Step 4: Write Your First Slash Command

Each command lives in its own file. This habit keeps index.js short and makes commands easy to find. Create src/commands/ping.js and add this code:

js

const { SlashCommandBuilder } = require('discord.js');

module.exports = {
  data: new SlashCommandBuilder()
    .setName('ping')
    .setDescription('Check that the bot is alive and see its latency.'),

  async execute(interaction) {
    const latency = Math.round(interaction.client.ws.ping);
    await interaction.reply(`Pong! Gateway latency is ${latency} ms.`);
  },
};

Every command exports two things. The data property describes the command to Discord, including its name and description. The execute function holds the logic that runs when someone uses the command.

Notice that the code calls interaction.reply(). Discord expects a response within three seconds. If your command needs more time, call interaction.deferReply() first, and then finish with interaction.editReply().

Step 5: Build the Main Bot File

Next, write the entry point. Open src/index.js and paste in the following code. It creates the client, loads every command file, and listens for interactions.

js

const fs = require('node:fs');
const path = require('node:path');
const {
  Client,
  Collection,
  Events,
  GatewayIntentBits,
  MessageFlags,
} = require('discord.js');

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

// Load every command file from the commands folder
client.commands = new Collection();
const commandsPath = path.join(__dirname, 'commands');
const commandFiles = fs
  .readdirSync(commandsPath)
  .filter((file) => file.endsWith('.js'));

for (const file of commandFiles) {
  const command = require(path.join(commandsPath, file));
  if ('data' in command && 'execute' in command) {
    client.commands.set(command.data.name, command);
  } else {
    console.warn(`Skipping ${file}: missing "data" or "execute".`);
  }
}

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

client.on(Events.InteractionCreate, async (interaction) => {
  if (!interaction.isChatInputCommand()) return;

  const command = interaction.client.commands.get(interaction.commandName);
  if (!command) return;

  try {
    await command.execute(interaction);
  } catch (error) {
    console.error(`Error in /${interaction.commandName}:`, error);
    const reply = {
      content: 'Something went wrong while running that command.',
      flags: MessageFlags.Ephemeral,
    };
    if (interaction.replied || interaction.deferred) {
      await interaction.followUp(reply);
    } else {
      await interaction.reply(reply);
    }
  }
});

client.login(process.env.DISCORD_TOKEN);

What the Main File Does

Several details deserve a closer look. First, the client requests only the Guilds intent, which matches what the bot needs. Second, the loader reads the commands folder, so adding a feature later means adding a file and nothing more.

Third, the code uses Events.ClientReady instead of the plain string "ready". This choice matters. Discord.js renamed that event to clientReady to avoid confusion with Discord’s own gateway event, and the old name triggers a deprecation warning. Using the constant keeps your Discord bot with Node.js working across versions.

Finally, the try and catch block protects your bot. If one command throws an error, the bot replies politely and keeps running. The MessageFlags.Ephemeral flag makes that error message visible only to the person who triggered it.

Step 6: Register Your Slash Commands

Writing a command file does not make it appear in Discord. You must also register it with Discord’s API. Create src/deploy-commands.js for that job:

js

const fs = require('node:fs');
const path = require('node:path');
const { REST, Routes } = require('discord.js');

const { DISCORD_TOKEN, CLIENT_ID, GUILD_ID } = process.env;

const commands = [];
const commandsPath = path.join(__dirname, 'commands');

for (const file of fs.readdirSync(commandsPath).filter((f) => f.endsWith('.js'))) {
  const command = require(path.join(commandsPath, file));
  commands.push(command.data.toJSON());
}

const rest = new REST().setToken(DISCORD_TOKEN);

(async () => {
  try {
    console.log(`Registering ${commands.length} command(s)...`);
    const data = await rest.put(
      Routes.applicationGuildCommands(CLIENT_ID, GUILD_ID),
      { body: commands },
    );
    console.log(`Registered ${data.length} command(s) successfully.`);
  } catch (error) {
    console.error(error);
  }
})();

Guild Commands vs Global Commands

This script registers commands for one server only, which is perfect for testing. Guild commands appear almost instantly, so you can iterate quickly. When you are ready to release the bot to everyone, swap Routes.applicationGuildCommands(CLIENT_ID, GUILD_ID) for Routes.applicationCommands(CLIENT_ID). Global commands reach every server, although they can take longer to show up.

Also remember that registration is a one-time task. Run it from your own computer whenever your command definitions change. You do not need to run it on your server each time the bot restarts.

Step 7: Run and Test Your Discord Bot With Node.js Locally

You are ready for the first run. Register the commands, and then start the bot in development mode:

bash

npm run deploy
npm run dev

If everything works, the terminal prints Logged in as YourBot#0000, and the bot turns green in your server’s member list. Type /ping in any channel. Discord shows your command in the autocomplete menu, and the bot answers with its latency.

If something fails, do not panic. The troubleshooting section later in this guide covers the most common errors, such as invalid tokens and missing access. For now, check that your .env values have no extra spaces or quotation marks.

Add More Features to Your Discord Bot With Node.js

A bot with one command is a start, but real projects need options, formatting, and richer replies. Fortunately, the pattern stays the same. Add a file, export data and execute, and register the command again.

A Dice Command With Options

Create src/commands/roll.js. This command accepts an optional number of sides:

js

const { SlashCommandBuilder } = require('discord.js');

module.exports = {
  data: new SlashCommandBuilder()
    .setName('roll')
    .setDescription('Roll a die.')
    .addIntegerOption((option) =>
      option
        .setName('sides')
        .setDescription('How many sides the die has (default 6).')
        .setMinValue(2)
        .setMaxValue(1000),
    ),

  async execute(interaction) {
    const sides = interaction.options.getInteger('sides') ?? 6;
    const result = Math.floor(Math.random() * sides) + 1;
    await interaction.reply(`🎲 You rolled a **${result}** on a d${sides}.`);
  },
};

Discord validates the minimum and maximum values before your code ever runs. As a result, you rarely need to check user input by hand for simple numeric options.

A Server Info Embed

Now create src/commands/serverinfo.js. Embeds make replies look polished:

js

const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');

module.exports = {
  data: new SlashCommandBuilder()
    .setName('serverinfo')
    .setDescription('Show details about this server.')
    .setDMPermission(false),

  async execute(interaction) {
    const { guild } = interaction;
    const embed = new EmbedBuilder()
      .setTitle(guild.name)
      .setColor(0x5865f2)
      .addFields(
        { name: 'Members', value: String(guild.memberCount), inline: true },
        {
          name: 'Created',
          value: `<t:${Math.floor(guild.createdTimestamp / 1000)}:D>`,
          inline: true,
        },
      );

    await interaction.reply({ embeds: [embed] });
  },
};

Run npm run deploy again so Discord learns about the two new commands. Then test both in your server. Because the dev script watches for changes, the bot restarts automatically after each save.

Where to Go From Here

With this foundation, you can grow in many directions. You could store data in a database, add buttons and select menus, or schedule recurring messages. Event-driven features, such as welcoming new members, need the privileged Server Members intent. Remember to enable it in the portal and in your client options at the same time.

Stuck on a tricky feature? An AI assistant can speed up debugging, provided you ask well. Our guide on how to write better prompts for AI coding tools shows how to get useful answers instead of confident guesses. For deeper API details, the official discord.js guide and the discord.js documentation are the best references.

Make Your Bot Production-Ready Before Hosting

Code that runs on your laptop is not automatically ready for a server. A hosted bot runs unattended for weeks, so it needs a few safeguards. Fortunately, each one takes only a few lines.

Handle Errors Globally

An unexpected error can crash a Node.js process. Add these handlers near the bottom of src/index.js, just above the client.login() line:

js

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

process.on('unhandledRejection', (reason) => {
  console.error('Unhandled promise rejection:', reason);
});

process.on('uncaughtException', (error) => {
  console.error('Uncaught exception:', error);
  process.exit(1);
});

Here is the logic. A rejected promise usually does not corrupt your app, so the bot logs it and continues. An uncaught exception, however, leaves the process in an unknown state. Exiting is safer, and your process manager will restart the bot cleanly.

Shut Down Gracefully

Hosts stop your app by sending a termination signal. If your code ignores it, the connection to Discord may linger for a moment. Add a short handler so the bot disconnects politely:

js

async function shutdown(signal) {
  console.log(`${signal} received. Closing the Discord connection...`);
  await client.destroy();
  process.exit(0);
}

process.on('SIGTERM', () => shutdown('SIGTERM'));
process.on('SIGINT', () => shutdown('SIGINT'));

Protect Your Token and Use Version Control

Never commit your token. Public repositories are scanned constantly, and Discord itself often detects leaked bot tokens and resets them. Because your .gitignore already excludes .env, you are covered, but double-check before every push.

Next, put the project under version control and push it to GitHub. Version control also gives you an easy way to deploy updates later. If Git still feels confusing, our roundup of the best Git tools for beginners will help you pick a friendly workflow.

Where to Host a Discord Bot With Node.js 24/7

Your bot works locally, so now it needs a permanent home. This choice matters more than it seems, because a poorly matched host leads to random downtime. Let’s look at the options clearly.

Why Your Laptop Is Not Enough

You could leave your computer running all day. However, your bot would go offline whenever the machine sleeps, restarts for updates, or loses Wi-Fi. A server in a data center avoids those problems. It stays powered, connected, and ready around the clock.

Hosting Options Compared

OptionTypical costEffortBest for
Your own computerFree, plus electricityLowTesting only
Raspberry Pi at homeOne-time hardware costMediumHobby bots and tinkerers
VPS (virtual private server)Often around $4 to $6 per monthMediumFull control and best value
Platform host such as RailwayFrom about $5 per monthLowFast deploys from GitHub
Free cloud tiersFree, with strings attachedHighExperiments

Prices change often. Hetzner, for example, raised its cloud prices more than once in 2026, so compare current rates before you commit.

Why Free Web Hosting Often Fails for Bots

Many beginners try a free web service first. Unfortunately, most free web tiers put an app to sleep after a short period without incoming HTTP traffic. Render’s free plan, for instance, spins a service down after 15 minutes without inbound requests.

A bot receives no inbound HTTP requests, because it talks to Discord over an outbound WebSocket. As a result, a sleeping host would treat your bot as idle and shut it down, which drops the connection. Keep-alive pings are a fragile workaround. For a deeper look at how these free plans behave, read our comparison of Render vs Railway for free Node.js hosting.

Oracle Cloud’s Always Free tier is another popular suggestion. It can work, but reports in 2026 describe a reduced Arm allowance, and Oracle’s documentation says idle free instances may be reclaimed. A lightweight bot sits idle most of the time, so that risk is real.

Our Recommendation

For most beginners, one of two paths makes sense. If you want the lowest cost and the most control, rent a small VPS and run the bot under PM2. If you would rather skip server chores, deploy from GitHub to Railway. Both keep your Discord bot with Node.js online 24/7, and both are covered step by step below.

Not sure where else to run Node.js projects? Our guide on where to deploy your first Node.js app covers the wider landscape.

Host Your Discord Bot With Node.js on a VPS With PM2

A VPS is a small Linux server you rent by the month. It gives you full control, predictable pricing, and plenty of room to grow. The steps below use Ubuntu, the most common choice.

Create and Secure the Server

First, create an Ubuntu server at any VPS provider. The smallest plan is enough for a typical bot, since a small discord.js bot often uses well under 200 MB of memory. Add your SSH key during setup, and then connect:

bash

ssh root@YOUR_SERVER_IP

Next, create a regular user so you do not run everything as root, and enable a basic firewall:

bash

adduser botuser
usermod -aG sudo botuser
ufw allow OpenSSH
ufw enable

Here is a pleasant security bonus. Your bot only makes outbound connections, so SSH is the only inbound port you need. Blocking everything else shrinks your attack surface considerably.

Install Node.js With nvm

Switch to the new user, and then install the Node Version Manager by following the install command on the nvm GitHub page. After that, install Node.js 24:

bash

nvm install 24
node --version

Using nvm keeps your Node.js version easy to upgrade later, which becomes useful as new LTS releases arrive.

Deploy the Code

Now clone your repository, install production dependencies, and create the environment file:

bash

git clone https://github.com/your-username/my-discord-bot.git
cd my-discord-bot
npm ci --omit=dev
nano .env
chmod 600 .env

Paste your DISCORD_TOKEN into .env, and save the file. The chmod 600 command ensures that only your user can read it. The server does not need CLIENT_ID or GUILD_ID, because registration happens from your own computer.

Keep the Bot Alive With PM2

If you start the bot with node src/index.js and close your SSH session, it stops. PM2 solves this problem. It runs your app in the background, restarts it after crashes, and relaunches it after a reboot. Install it globally:

bash

npm install -g pm2

Then create ecosystem.config.js in your project folder:

js

module.exports = {
  apps: [
    {
      name: 'my-discord-bot',
      script: 'src/index.js',
      node_args: '--env-file=.env',
      autorestart: true,
      max_memory_restart: '300M',
    },
  ],
};

Start the bot, and then save the process list so PM2 can restore it later:

bash

pm2 start ecosystem.config.js
pm2 status
pm2 logs my-discord-bot
pm2 save
pm2 startup

The pm2 startup command prints one more command for you to copy and run with sudo. Once you run it, your Discord bot with Node.js comes back automatically after every server reboot. For more options, see the PM2 quick start documentation.

An Alternative: systemd

Linux already includes a process manager called systemd. If you prefer fewer tools, create /etc/systemd/system/discord-bot.service with the following content. Replace the Node path with the output of which node:

ini

[Unit]
Description=My Discord bot
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=botuser
WorkingDirectory=/home/botuser/my-discord-bot
EnvironmentFile=/home/botuser/my-discord-bot/.env
ExecStart=/path/to/node src/index.js
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Then enable and start it with sudo systemctl enable --now discord-bot. Check the logs anytime with journalctl -u discord-bot -f.

Host Your Discord Bot on Railway From GitHub

Prefer to skip server management? Railway deploys straight from a GitHub repository, and it handles restarts for you. The workflow takes only a few minutes.

  1. Push your project to GitHub. Confirm that .env is not in the repository.
  2. Sign in to Railway with your GitHub account.
  3. Click New Project, choose Deploy from GitHub repo, and select your bot.
  4. Open the Variables tab and add DISCORD_TOKEN with your bot token.
  5. Let Railway build and start the app. It reads your package.json, installs dependencies, and runs npm start.
  6. Open the deployment logs and look for the “Logged in as” message.

You do not need to generate a public domain, because a bot does not serve web pages. Also, add an engines field to package.json so Railway uses a modern runtime, for example "engines": { "node": ">=22" }.

Watch Your Costs on Railway

Railway bills for the resources you use, and a bot that idles at low memory usually costs little. In most cases, the $5 Hobby plan covers a small bot. Even so, set a usage limit in your account on day one, so a bug can never surprise you with a large bill.

Be careful with the free plan. Railway’s sleep behavior depends on outbound traffic, and a bot’s constant gateway connection counts as outbound activity. Therefore, a bot is a poor fit for sleep-based free tiers. Our Render vs Railway guide explains the current limits in detail.

Run Your Discord Bot With Node.js in Docker (Optional)

Docker packages your app and its dependencies into a single image. It is optional for beginners, but it makes deployments repeatable and portable between hosts. Create a Dockerfile in the project root:

dockerfile

FROM node:24-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY src ./src
USER node
CMD ["node", "src/index.js"]

Then build and run the container on any server with Docker installed:

bash

docker build -t my-discord-bot .
docker run -d --name my-discord-bot --restart unless-stopped --env-file .env my-discord-bot

The --restart unless-stopped flag plays the same role as PM2: Docker restarts the container after crashes and reboots. To learn more, browse the official Docker documentation.

Update Your Bot Without Stress

Sooner or later, you will add features. A simple routine keeps updates safe. On a VPS, log in and run these commands:

bash

cd ~/my-discord-bot
git pull
npm ci --omit=dev
pm2 restart my-discord-bot

On Railway, each push to your main branch triggers a fresh deploy automatically. In both cases, remember to run npm run deploy from your computer whenever you change a command’s name, description, or options. Otherwise, Discord keeps showing the old version.

For extra safety, test changes on a second “development” bot application in your test server. Doing so keeps experiments away from your live community.

Monitor Your Discord Bot With Node.js

Hosting is not a “set it and forget it” job. A good monitoring habit catches problems before your users do.

  • Read the logs regularly. Run pm2 logs on a VPS, or open the deployment logs on Railway. Repeated errors often reveal small bugs.
  • Watch memory. Use pm2 monit to see CPU and memory live. A slowly rising memory line often signals a leak.
  • Add an uptime heartbeat. Many monitoring services accept a ping from your code every few minutes. If the pings stop, they alert you by email or chat.
  • Send errors to a private channel. A webhook in a private Discord channel can post crash reports directly to your phone.

Finally, keep your server patched. Run sudo apt update && sudo apt upgrade every few weeks, and update Node.js when a new LTS line becomes available.

Troubleshooting Common Problems

Even careful developers hit errors. Here are the most common ones, with quick fixes.

  • “An invalid token was provided.” Your token is wrong, expired, or contains stray spaces or quotes. Reset it in the Developer Portal and paste it again.
  • “Used disallowed intents.” Your code requests a privileged intent that you have not enabled. Either turn it on in the Bot tab or remove it from your client options.
  • Slash commands do not appear. You may have skipped registration, used the wrong GUILD_ID, or invited the bot without the applications.commands scope. Run npm run deploy, and then reload Discord.
  • “Missing Access” or “Missing Permissions.” The bot lacks channel permissions. Check the channel settings and the bot’s role, and confirm that it can view the channel and send messages.
  • The bot goes offline when you close SSH. You started it in the foreground. Use PM2, systemd, or Docker instead.
  • “Cannot find module.” Dependencies are missing on the server. Run npm ci --omit=dev inside the project folder.
  • The bot restarts in a loop. Run pm2 logs and read the first error. A bad token or a syntax error is the usual cause.

If you still feel stuck, search the exact error message along with “discord.js.” Chances are good that someone has solved it already.

Scale and Stay Compliant as Your Bot Grows

A small bot rarely needs special planning. Nevertheless, a few milestones are worth knowing before you reach them.

First, Discord requires sharding once a bot is in 2,500 servers. Sharding splits the work across multiple connections, and discord.js includes a built-in sharding manager for the job. Second, verification and privileged intent approval come into play near 100 servers, as mentioned earlier. Start preparing your privacy policy and a clear explanation of your intent usage well before that point.

Meanwhile, keep your dependencies current. Run npm outdated occasionally and update discord.js in small steps. Also watch the release notes, because a future major version, discord.js 15, will remove some deprecated features. Writing code with Events.ClientReady and the other modern constants now makes that upgrade much smoother.

Frequently Asked Questions

Can I host a Discord bot with Node.js for free?

Sometimes, yes, but with limits. Free web tiers usually sleep without incoming traffic, which breaks a bot. Free cloud VMs can work, although availability and reclaim policies vary. For reliable uptime, a small paid VPS or Railway’s Hobby plan is a better investment.

Do I need Express or a web server?

No. A bot connects out to Discord, so it needs no web server, domain, or open port. Some hosts expect an HTTP port, but you can ignore that requirement when you choose a host that supports background processes.

How much memory does a Discord bot need?

A small discord.js bot typically runs comfortably in a few hundred megabytes at most. Memory use grows with the number of servers and the data you cache. Therefore, start small and watch the numbers with a tool such as pm2 monit.

Which library should I use?

Discord.js is the most widely used and best-documented library for building a Discord bot with Node.js, so it is the best choice for beginners. Alternatives exist, including Eris and Oceanic, but you will find far more tutorials and community help for discord.js.

What should I do if my token leaks?

Act immediately. Open the Developer Portal, go to the Bot tab, and click Reset Token. Then update the new token on your host and restart the bot. After that, remove the leaked token from your Git history if it ever reached a repository.

Should I use slash commands or message commands?

Use slash commands. Discord designed them for bots, and they work without the privileged Message Content intent. Prefix commands, such as !ping, force you to request that intent and to apply for approval as your bot grows.

Conclusion: Your Discord Bot With Node.js Is Live

You have come a long way. You created an application, invited a bot, and wrote a clean, modular Discord bot with Node.js using discord.js 14. You added options and embeds, hardened the code for production, and deployed it where it runs 24/7.

Here is the short recap. Use slash commands and the Guilds intent. Keep secrets in environment variables, never in Git. Register commands from your own computer. Finally, run the bot under PM2, systemd, Docker, or a platform like Railway so it restarts itself.

From here, the best next step is to build something you actually want. A moderation helper, a study-group reminder, or a game bot for your friends will teach you more than any tutorial. Pair your new skills with the right learning tools, such as the ones in our list of the best AI tools to learn programming faster, and your projects will grow quickly.

Keep in mind that platforms change their pricing and limits often. Check each provider’s current terms before you commit, and enjoy watching your bot stay online while you sleep.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *