Host a Node.js Discord bot
A Discord bot is not a website: it opens a persistent connection to the Discord gateway and needs no public HTTP port. On app hosting it must stay alive, reconnect after a network drop and keep its token out of the code. Here is a minimal setup and the details that separate a bot running for an hour from one running for weeks.
Prepare the project
Pick a recent Node.js runtime from those offered (22 LTS is a good balance). The project needs at least package.json, index.js and the dependencies installed by the platform.
npm install discord.jsconst { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages]
});
client.once('ready', (c) => console.log(`logged in as ${c.user.tag}`));
client.on('messageCreate', async (message) => {
if (message.author.bot) return;
if (message.content === '!ping') await message.reply('pong');
});
client.login(process.env.DISCORD_TOKEN);client.login blocks the process and maintains the connection. No listen is needed. Create the token in the Discord developer portal and put it in the panel environment variables, never in index.js.
Intents and commands
Intents declare what the bot receives. Request the minimum: Guilds is enough for slash commands. MessageContent is privileged: enable it in the developer portal, otherwise Discord refuses the connection with Used disallowed intents.
For slash commands, register once, not on every start. A separate script or a REGISTER_COMMANDS=true variable that you later disable avoids duplicates and unnecessary API calls.
Memory and stability
discord.js caches guilds, channels and members. On a large server these caches quickly consume the plan's memory.
- Do not enable
GuildMembersunless needed. - Avoid walking and storing every member at startup.
- Watch
Mapand array structures that grow without bound. - Do not leave an unreferenced
setIntervalif you recreate it on every event.
The library handles reconnection, but an uncaught exception in an event handler can bring the process down. Add an error listener and log without exiting abruptly. Rate limits are handled by the internal queue: avoid loops that send messages in bursts.
Token security
The token grants full control of the bot. If it leaks, reset it immediately in the developer portal: the old one is invalidated. Also check Git history if it was committed; removing it from the last commit is not enough. Grant only the permissions the bot needs and validate sensitive actions in code rather than trusting command parameters.
Check
The console shows logged in as ..., the bot appears online, a command replies and memory stays stable after thirty minutes. A reconnect loop usually means an invalid token or a refused intent, not a network issue.
Advertisement
Was this article helpful?
Read next
- Redeploy a Node.js applicationReplace code, reinstall dependencies, restart and verify without a mixed state.
- Deploy an Express APIStructure an Express API, validate input and expose a health route.
- Read Node.js application logsRead stdout and stderr in the console, spot a restart loop and log without leaks.