TypeScript on the Node.js application has one gotcha worth understanding before you start, and it's better to hear it up front than to fight it. This guide gives you a working typed discord.js bot and explains the trick that makes it run.
| At a glance | |
|---|---|
| You need | comfort with the discord.js bot guide, a bot token from Your first Discord bot, and a Falix server running the Node.js application |
| Time | about twenty minutes |
The bot logic is identical to the discord.js guide — only the language and build step differ.
The trap, honestly
The Node.js application starts your app by running your Main file. If that file ends in .js it runs node yourfile.js; anything else falls back to a ts-node path — and that path fails on current Node versions with ERR_UNKNOWN_FILE_EXTENSION.
⚠️ Heads up: Pointing the Main file straight at a
.tsfile simply does not work here.
The fix isn't to run TypeScript directly — it's to compile TypeScript to JavaScript first, then run the JavaScript. This template does exactly that, automatically, and it's a pattern that works for any TypeScript project on the Node app, not just bots.
How the self-compiling trick works
Remember that the Node.js application runs npm install on every start whenever a package.json is present. This template hooks into that:
- Its
package.jsondefines apostinstallscript that runstsc(the TypeScript compiler), and liststypescriptas a dev dependency. - Its
tsconfig.jsonsetsrootDir: srcandoutDir: distwithmodule: commonjs— read source fromsrc/, write compiled.jsintodist/. - The template has already set the server's Main file variable to
dist/index.js.
So every start goes: npm install runs → postinstall fires → tsc compiles src/ into fresh JavaScript in dist/ → Node runs dist/index.js. You never build by hand; starting the server is the build.
1. Deploy the starter
Use the template on this page. Besides the files (src/index.ts, package.json, tsconfig.json, .env), it sets the Main file to dist/index.js for you. Deploying onto a server running a different application switches it to Node.js first — a reinstall that wipes files, with a warning.
2. Paste in your token
In the File Manager, edit .env and replace YOUR_TOKEN_HERE with your token. Save.
3. Start it
Press Start. The console runs npm install, then you'll see tsc compile, and finally:
Listening as YourBot#0000
As with any Node bot, that Listening line is also what flips the server to online. Type /ping in your server to confirm (give global commands a few minutes on the very first run).
What to edit — and what never to touch
Edit src/index.ts. That's your bot. The logic is the same discord.js you'd write in plain JavaScript, just typed:
import 'dotenv/config';
import { Client, Events, GatewayIntentBits } from 'discord.js';
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.once(Events.ClientReady, async (c) => {
await c.application.commands.set([
{ name: 'ping', description: 'Check that the bot is alive' },
]);
console.log(`Listening as ${c.user.tag}`);
});
client.on(Events.InteractionCreate, async (interaction) => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === 'ping') {
await interaction.reply(`Pong! ${client.ws.ping} ms`);
}
});
client.login(process.env.DISCORD_TOKEN);
Adding commands works exactly as in the discord.js guide: register in the set([...]) array, handle in InteractionCreate, then restart so it recompiles.
⚠️ Heads up: Never edit
dist/. Everything in there is generated bytscand overwritten on the next start — your changes would vanish (dist/is even in.gitignorefor that reason). The rule:src/is yours,dist/belongs to the compiler.
To add libraries, use the Packages page as usual; it updates package.json and a restart recompiles and reloads.
The simpler alternative: Bun
If the build step feels like overhead, the Bun application runs TypeScript files natively — no tsc, no dist/, no postinstall. You'd point the Main file straight at src/index.ts and it just runs. If you're starting fresh and don't need Node specifically, it's the lighter path. See Bun on Falix.
Troubleshooting
error TS...during install — a compile error, printed whilepostinstallruns. Don't be fooled if the bot still comes up: it may be running the previous successful build fromdist/. Fix the code insrc/and restart until the install is clean.- Edits seem to do nothing — you edited
dist/instead ofsrc/.dist/is regenerated on every start. Make the change insrc/and restart. TokenInvalid— same as any bot: the token in.envis wrong or was reset. Paste a fresh one from the Developer Portal./pingdoesn't appear — first-time global registration is slow; wait a few minutes, and confirm the bot was invited with theapplications.commandsscope.