How to host a Discord bot (discord.js) on OuiPanel
This guide shows how to host a Discord bot written with discord.js (JavaScript, Node.js) on a OuiHeberg Node.js server, managed in OuiPanel. The bot runs continuously on the server, even when your computer is off. You need a bot created on the Discord Developer Portal, its token and the bot's files (index.js, package.json…).
Create the bot on Discord
Already have your bot and its token? Skip to the next section.
Create the application
Go to the Discord Developer Portal and log in with your Discord account.
Click New Application.
Name your application, for example "My Bot", accept the terms, then click Create.

Create the bot
In the left menu, click Bot. Recent applications already have their bot. If the Add Bot button shows up, click it and confirm with Yes, do it! in the window.
Get the token
In the Bot section, click Reset Token.
Confirm, then copy the token shown.
The token works like a password. Anyone who gets it can control your bot. Never share it and never put it in public code (GitHub, etc.).
Enable the intents
Still in the Bot section, scroll down to Privileged Gateway Intents and enable the intents you need.
| Intent | Use |
|---|---|
| PRESENCE INTENT | Optional |
| SERVER MEMBERS INTENT | Optional |
| MESSAGE CONTENT INTENT | Required to read message content |

Without MESSAGE CONTENT INTENT, your bot cannot read message content, and a command like
!pinggets no answer.
Invite the bot to your Discord server
In the left menu, click OAuth2 › URL Generator.
Under Scopes, tick bot and applications.commands.
Under Bot Permissions, tick the permissions you need, or Administrator for all of them.
Copy the URL generated at the bottom of the page, open it and invite the bot to your Discord server.

Prepare the bot files
File structure
Your bot should have this structure.
MyBot/
├── index.js ← Main file (or bot.js, main.js...)
├── package.json ← npm dependencies
├── .env ← Bot's token (created on the server)
├── commands/ ← (Optional) Commands folder
└── events/ ← (Optional) Events folder
The package.json file
Create a package.json file with the discord.js and dotenv dependencies.
{
"name": "my-discord-bot",
"version": "1.0.0",
"description": "My Discord bot",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"discord.js": "^14.14.1",
"dotenv": "^16.3.1"
}
}
Adjust
"main": "index.js"to the name of your main file (bot.js,main.js, etc.).
The main file (index.js)
Create your main file. It loads the token with dotenv.
// Load environment variables from .env
require('dotenv').config();
const { Client, GatewayIntentBits } = require('discord.js');
// Create the Discord client
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent
]
});
// Event: Bot ready
client.once('ready', () => {
console.log(`Bot connected as ${client.user.tag}`);
});
// Event: Message received
client.on('messageCreate', message => {
if (message.author.bot) return;
// Use the prefix from .env (optional)
const prefix = process.env.PREFIX || '!';
if (message.content === `${prefix}ping`) {
message.reply('Pong!');
}
});
// Error handling
process.on('unhandledRejection', error => {
console.error('Unhandled error:', error);
});
client.on('error', error => {
console.error('Discord error:', error);
});
// Connect with the token from .env
client.login(process.env.DISCORD_TOKEN);
The
require('dotenv').config();line must be the first line of your file.
Upload the files to OuiPanel
The File Manager has no upload button. Files are sent by drag and drop.
Log in to OuiPanel at dash.ouipanel.com and open your Node.js server.
In the side menu, click File Manager.
Delete the default files, if any.
From your computer, drag
index.js,package.jsonand your folders (commands/,events/…) onto the page.When the "Drop your files here" overlay appears, release them.
Each file sent this way is limited to 100 MB.

Do not upload your
.envfile. You will create it directly on the server in the next step.
Over SFTP
For many files, or files over 100 MB, use SFTP. Connect with FileZilla, drag the whole content of your bot folder, then check that everything arrived. The guide How to connect via SFTP with FileZilla explains the connection.
Create the .env file
Never put your token directly in the code. Create a .env file on the server.
In the File Manager, in Root, click Create file.
In the "Create new file" window, type
.envin File name, with the leading dot, then click Create file.Click
.envto open it in the editor and paste the content below.Replace
your_token_herewith your token, then click Save.
# Discord bot token
DISCORD_TOKEN=your_token_here
# Command prefix (optional)
PREFIX=!
Example with a real token:
DISCORD_TOKEN=MTIzNDU2Nzg5MDEyMzQ1Njc4OQ.ABcdEF.abcdefghijklmnopqrstuvwxyz123456
PREFIX=!
No spaces around the
=.No quotes around the values.
Never share this file.

Here is the final structure on the server.
Server Root/
├── .env ← Contains DISCORD_TOKEN
├── index.js ← Your code
├── package.json ← Dependencies
└── node_modules/ ← (created automatically)
Set the main file and the Node.js version
OuiPanel needs to know which file to run at startup. On a Node.js server, this setting is a server variable.
Open Configuration › Server Settings.
In the Server Launch card, check the System version. The list offers Node.js 12, 14 and every version from 16 to 26. Version 24, the LTS release, suits discord.js.
In the Environment Variables card, type your file name in Main file (main file; variable names are shown in French).
Click the tick to the right of the field (Save).
| Your main file | Value of Main file |
|---|---|
index.js | index.js |
bot.js | bot.js |
main.js | main.js |
src/index.js | src/index.js |
app.js | app.js |
The same card offers Additional Node packages and Node packages to uninstall, to add or remove npm packages (names separated by spaces). The Additional arguments field passes options to Node.js.

The name must match your file exactly, including upper and lower case.
Start and test the bot
Start the server
In the side menu, click Console, then Start. At startup, the server installs the dependencies from package.json with npm install, then runs your file.
> npm install
added 45 packages in 3s
> node index.js
Bot connected as MyBot#1234
Check on Discord
The console should show this line.
Bot connected as MyBot#1234
Open Discord. Your bot shows as online, with a green dot.
Try the
!pingcommand. The bot answers "Pong!".
Deploy from a Git repository
Your code lives on GitHub, GitLab, Bitbucket or Codeberg? The Deployment page fetches the repository and installs the dependencies for you, instead of uploading files by hand.
In the side menu, click Deployment.
In the Link a repository block, fill in Repository address and Branch.
Under Repository access, choose Public repository, or one of the two private repository options (deploy key or access token).
Tick Deploy on every push to the branch if you want automatic updates, then click Save.
Click Deploy now.
Each deployment restarts the server, which stays stopped while dependencies are installed. If the install fails, the previous version starts again. Files not tracked by Git, such as your .env, stay in place. Before the first deployment, the panel backs up the server.

For a private repository, the deploy key is recommended. The panel generates a key for this server, to add to the repository as read-only.
Run multiple bots with a single plan
A Node.js server runs a single file at startup. To run several bots on the same plan, that file can be a launcher that starts each bot in its own process. If one bot crashes, the others keep running. They all share the plan's memory and CPU.
Upload your bots' files to the server root, for example
bot1.jsandbot2.js.Put the dependencies of all the bots in the
package.jsonfile at the root.In the
.envfile, give each bot's token its own name, such asDISCORD_TOKEN_1andDISCORD_TOKEN_2. Have each bot read its own token, for example withclient.login(process.env.DISCORD_TOKEN_1).At the root, create a
launcher.jsfile with the content below, then adjust thebotslist.In Configuration › Server Settings, type
launcher.jsin Fichier principal (main file), then click the tick (Save).In the Console, click Restart.
// Starts each bot in its own process
const { spawn } = require('child_process');
const readline = require('readline');
// Your bots' files, at the server root
const bots = ['bot1.js', 'bot2.js'];
for (const file of bots) {
const child = spawn(process.execPath, [file]);
// Prints each line from the bot in the console, prefixed with its name
readline.createInterface({ input: child.stdout })
.on('line', (line) => console.log(`[${file}] ${line}`));
readline.createInterface({ input: child.stderr })
.on('line', (line) => console.error(`[${file}] ${line}`));
child.on('exit', (code) => console.log(`[${file}] stopped (code ${code})`));
}
In the console, each line starts with the name of the bot that wrote it, for example [bot1.js] Bot connected as MyBot#1234. When a bot stops, the launcher shows its exit code.
The launcher does not restart a bot that stops. To start it again, restart the server.
Troubleshooting
The bot does not start
| Error | Fix |
|---|---|
Cannot find module 'discord.js' | Check package.json and restart. |
Cannot find module 'dotenv' | Add dotenv to package.json. |
Error: Cannot find module './index.js' | Wrong value in the Main file variable. |
ENOENT: no such file or directory | The file given does not exist. |
Token error
| Error | Fix |
|---|---|
An invalid token was provided | Check the token in .env. |
TOKEN_INVALID | Regenerate the token on the Discord Developer Portal. |
Used disallowed intents | Enable the intents on the Discord Developer Portal. |
The bot does not read messages
| Cause | Fix |
|---|---|
| MESSAGE CONTENT INTENT disabled | Enable it on the Discord Developer Portal. |
| Wrong intents in the code | Add GatewayIntentBits.MessageContent. |
The .env file is not read
| Cause | Fix |
|---|---|
| dotenv missing | Check that it is listed in package.json. |
require in the wrong place | require('dotenv').config(); must be the first line. |
| Wrong file name | The file must be named exactly .env. |
npm install fails
| Error | Fix |
|---|---|
package.json not found | Check that the file is at the root. |
ERESOLVE unable to resolve | Update the versions in package.json. |
Best practices
Protect the .env file
| Do | Avoid |
|---|---|
Keep .env on the server only | Sharing .env |
Create .env directly in OuiPanel | Uploading .env from your computer |
Add .env to .gitignore | Committing .env to GitHub |
Recommended .gitignore file in your project:
# Environment variables
.env
# Node modules
node_modules/
Security and performance
Never share your token, and regenerate it if it leaks.
Create
.envdirectly on the server.Only enable the intents you need.
Handle errors with
try/catchand add logs for debugging.
Organize a larger bot
For a more organized bot, split commands and events.
MyBot/
├── index.js ← Entry point
├── package.json
├── .env ← Created on the server
├── commands/
│ ├── ping.js
│ ├── help.js
│ └── info.js
├── events/
│ ├── ready.js
│ └── messageCreate.js
└── config.json ← Non-sensitive configuration
Need help?
Open a ticket from Tickets › Open a Ticket, or from the Contact support tile at the bottom of your server's page in the client area. You can also ask your question on the OuiHeberg Discord.
Deploy your Node.js applications with our optimized hosting and dedicated support.
View plans →