discord.js hosting, deployed from GitHub
A discord.js bot is the easiest kind to host badly: node index.js in a terminal works until the terminal closes. Here the repository deploys itself, runs around the clock in its own sandbox, and redeploys on every push. The first bot is free.
Make the repository deployable
package.json is the contract. A real start script (that is what gets run), an engines.node field (discord.js v14 wants Node 18 or newer; declare it instead of hoping), and a committed lockfile so installs are reproducible. npm, pnpm and yarn all work; a packageManager pin is respected.
The token from the environment: client.login(process.env.DISCORD_TOKEN). Request only the intents you use; MessageContent needs the Developer Portal toggle too, and the gateway rejects logins that ask for privileged intents without it.
Slash commands: register once, not on every boot
The classic mistake is calling REST.put(Routes.applicationCommands(...)) on startup. It works until Discord rate-limits your deploys, because every restart re-registers everything. Keep a separate deploy-commands.js you run when commands change. Your host restarts the bot more often than you think (crashes, redeploys, maintenance); boot should be side-effect free.
Deploy it
- Host a bot, connect GitHub, pick the repository. Node.js is detected from package.json.
- Set
DISCORD_TOKENand other secrets as environment variables. - Deploy: clone, install, start, in an isolated sandbox with a live console.
- Every push to the default branch redeploys. On a crash the bot restarts and the crash doctor reads the stack trace; nine times out of ten it is a bad token or a missing intent.
The checklist
startscript,engines.node, lockfile committed- Token and API keys in environment variables,
.envin.gitignore - Slash-command registration out of the boot path
- Intents matching the Developer Portal toggles
- Data in a managed database or on the bot's persistent disk, not in memory
Frequently asked questions
Which Node.js version runs?
A current LTS by default; engines.node in package.json picks a specific major. TypeScript bots build with a build command or a Dockerfile on paid tiers.
Does a discord.js bot fit the free tier?
A typical v14 bot idles around 80 to 150 MB, so yes. Voice and music bots want the Pro tier.
Can I use pnpm or yarn?
Yes. A pnpm-lock.yaml, yarn.lock or packageManager pin selects the package manager; preinstall hooks such as only-allow are respected.
How do I keep secrets out of the repository?
Environment variables in the panel, edited on the app page; the bot reads process.env. Never commit a .env file.