The Node.js template runs Node.js 22/24. On start it installs your production dependencies when they're missing or package.json has changed, then runs your main file.
Lavalink music servers are a free one-click template on plans with 512MB or more RAM; it uses your plan's memory.
Deploy in four steps
- Upload
package.json,package-lock.jsonif you have one, and your source in the file manager or over SFTP. Leavenode_modulesout, because it is installed on start. - Set Main file (
MAIN_FILE) to your entry file. The default isindex.js. - Paste your token into Bot token (
BOT_TOKEN) in the panel, and read it in code fromprocess.env.BOT_TOKEN. - Restart and wait for
BOT_READYin the console.
A minimal bot
This bot registers a /ping command, answers it with pong, and prints the ready line.
{
"name": "my-bot",
"private": true,
"type": "module",
"dependencies": {
"discord.js": "14.21.0"
}
}import { Client, Events, GatewayIntentBits } from 'discord.js';
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.once(Events.ClientReady, async (ready) => {
await ready.application.commands.set([
{ name: 'ping', description: 'Replies with pong' },
]);
console.log('BOT_READY');
});
client.on(Events.InteractionCreate, async (interaction) => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === 'ping') await interaction.reply('pong');
});
await client.login(process.env.BOT_TOKEN);This sample registers its commands each time it starts, which is fine for a few commands. Larger bots usually register from a separate script.
What runs on start
# with Auto update on: get the latest code from GitHub first
# if the main file is missing, the start stops here
# only when node_modules is missing or the package files changed
$ npm ci --omit=dev || npm install --omit=dev
$ node index.js
BOT_READYdevDependencies are skipped, so list anything the bot needs at runtime under dependencies. If you write TypeScript, compile it before you upload and point Main file at the built JavaScript file.
Deploy from GitHub
On Free for public repositories, and on paid plans for public or private repositories:
- Set Git repository (
GIT_REPO) to the clone URL and Git branch (GIT_BRANCH) to your branch, usuallymain. For a private repository, put a read-only token in Git token (GIT_TOKEN). - Set Auto update (
AUTO_UPDATE) to1. - Restart the bot. The next start clones the repository into the server. Every start after that fetches the branch.
- To restart on every push, connect the repository and branch on your account page and add the webhook it shows to the repository.
After an update, the console prints DEPLOY_COMMIT= and the commit it is running. If it says git update failed, check the token and the branch name.
With Auto update on, every start resets tracked files to the branch. Make changes in the repository instead.
What happens on the first start
Nothing on the server is deleted. Files that clash with the repository move to a backup folder named pre-git-backup- plus the UTC date and time, such as pre-git-backup-20261024221500. Files with other names stay where they are. If nothing clashes, no backup folder is left behind and the console says First git deploy done. When files clash, the console shows:
First git deploy done. Files with the same names as files in the repository were moved to pre-git-backup-20261024221500/.If the console says git clone failed, your files were not changed. Check the repository URL, the token, and that the branch exists, then restart.
If it says First git deploy stopped, leave the backup folder and the .git-first-clone folder as they are, and contact us before you restart.
Getting your old files back
- Open the
pre-git-backup-folder in the file manager or over SFTP. - Download anything you want to keep.
- To use one of those files in the bot, commit it to the repository. A file copied back onto the server is replaced by the repository's version on the next start.
- Delete the backup folder when you're done, because it counts toward your disk.
Reinstalling with GitHub connected
Reinstall keeps your files. With Git repository connected, installation defers fetching code to the next start with Auto update on, so a nonempty folder does not make the reinstall fail. Open the bot console during installation to see its output.
To recover a failed install, or to pause fetching while you check files:
- Clear Git repository and save.
- Reinstall the server from Settings in your bot dashboard. Your files are kept.
- Set Git repository back to the clone URL, keep Auto update at
1, and restart. The server still has its git history from the first start, so it fetches the branch as usual.
Free supports public HTTPS GitHub repositories only, with a shallow clone and a size check against the configured free disk limit. A repository that is private, unavailable or too large is blocked. Connection changes, Git-enabled starts and pushes share a limit of 20 deploy actions per account per hour. Private tokens are available only on paid plans. Variables and the token are covered in environment variables and tokens.
Still stuck? Contact support