Your first slash command
Register a /hello command, reply from the app, then change the text and restart only the app—no gateway reconnect.
This guide matches the npm create shardwire Express Server template (default): a register script (src/register.ts) plus interactionCreate in src/app.ts (alongside Express GET /health on PORT). Scaffold with npm create shardwire or read the template source under packages/create-shardwire/templates/express-server on GitHub.
What you will feel
After this works, change the reply string in src/app.ts, save, and restart only npm run app. The slash response updates without the long “bot is starting…” pause—because The Connection and Discord gateway stayed up in the bot terminal.
Prerequisites
- Finished Getting started with the Express Server scaffold or equivalent (bot + app running).
- Node.js 22+.
- A Discord Application ID (same as your bot’s application) and a guild id where you can install the bot (guild commands appear instantly for testing).
Add to your .env (uncomment the two lines in .env.example if you started from npm create shardwire):
DISCORD_APPLICATION_ID— Developer Portal → your app → Application ID.DISCORD_GUILD_ID— Server ID (enable Developer Mode → right‑click server → Copy ID).
Slash commands and registration
Shardwire delivers interactionCreate and interaction actions over The Connection. Registering the slash command with Discord is a separate one-time step (Discord REST API). That keeps your command list explicit and versioned—see replyToInteraction.
Keep npm run bot running in terminal A.
Run npm run register once (from your project root). This creates a /hello command in your test guild.
Run npm run app in terminal B (or restart it after edits).
In Discord, type /hello. You should see Hello from Shardwire! (or whatever string you put in code).
Edit the reply text in src/app.ts, save, restart only terminal B. Run /hello again—the new text appears without restarting the bot process.
What the app code is doing
Your connectBotBridge call (above this handler in src/app.ts) sets appName to the scaffold’s manifest name derived from the project directory— leave it as generated so capabilities and filtering stay consistent. The Express Server template names the bridge client bridge:
bridge.on('interactionCreate', async ({ interaction }) => {
if (interaction.kind !== 'chatInput' || interaction.commandName !== 'hello') return;
const result = await bridge.actions.replyToInteraction({
interactionId: interaction.id,
content: 'Hello from Shardwire!',
});
if (!result.ok) {
console.error(result.error.code, result.error.message);
}
});You listen for interactionCreate, check for a slash interaction (chatInput) and your command name, then call replyToInteraction. Always branch on result.ok.
Nothing happens?
- Confirm the
Guildsintent on the bot (needed for guild slash commands). - Re-run
npm run registerif you changed command name or guild. - Check Troubleshooting for
capability-not-availableand connection errors.