Only show guides for your app
The Node.js application can't run a .ts file directly, so this bot compiles itself on every start — here's the recipe, why it works, and what to edit.
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 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.
Remember that the Node.js application runs npm install on every start whenever a package.json is present. This template hooks into that:
package.json defines a postinstall script that runs tsc (the TypeScript compiler), and lists typescript as a dev dependency.tsconfig.json sets rootDir: src and outDir: dist with module: commonjs — read source from src/, write compiled .js into dist/.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.
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.
In the File Manager, edit .env and replace YOUR_TOKEN_HERE with your token. Save.
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).
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.
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.
error TS... during install — a compile error, printed while postinstall runs. Don't be fooled if the bot still comes up: it may be running the previous successful build from dist/. Fix the code in src/ and restart until the install is clean.dist/ instead of src/. dist/ is regenerated on every start. Make the change in src/ and restart.TokenInvalid — same as any bot: the token in .env is wrong or was reset. Paste a fresh one from the Developer Portal./ping doesn't appear — first-time global registration is slow; wait a few minutes, and confirm the bot was invited with the applications.commands scope.