Installation
Prerequisites
Section titled “Prerequisites”Before getting started with Warden, make sure your local machine has the following installed:
Scaffolding a new project
Section titled “Scaffolding a new project”The easiest way to create a new Warden project is by using the create-@warden CLI. This command will guide you through setting up a fresh project with sensible defaults:
pnpm create @warden my-mod-botDuring installation, the scaffolder will ask a few questions about which features you’d like to include:
? Project name: my-mod-bot? Database: None / Drizzle? Cache: None / Redis? Localization: Yes / NoDon’t worry if you’re not sure what you’ll need — you can always add these later by installing the relevant plugin packages.
Once the scaffolder has finished, navigate into your new project and install the dependencies:
cd my-mod-botpnpm installEnvironment variables
Section titled “Environment variables”Before you can start the bot, you’ll need to configure a few environment variables. The scaffolder has already created a .env.example file with all available options. Copy it to .env:
cp .env.example .envAt minimum, you’ll need a Discord bot token and application ID. If you haven’t created a Discord application yet, head to the Discord Developer Portal and create one — you’ll find the token and application ID there.
DISCORD_TOKEN=your-bot-tokenDISCORD_APPLICATION_ID=your-application-idStarting the development server
Section titled “Starting the development server”-
If you selected a database or cache during scaffolding, start the Docker services first:
Terminal window docker-compose up -d -
Then, start the bot in development mode:
Terminal window pnpm dev
And that’s it — your bot is online and ready to go. The development server uses tsx watch, which means any changes you make to your source files will automatically restart the bot.
When you’re ready to start building, head over to Your First Bot.
Manual setup
Section titled “Manual setup”Of course, if you prefer to set things up yourself, you’re free to do so. Start by creating a new project and installing the core dependencies:
mkdir my-mod-bot && cd my-mod-botpnpm initpnpm add @warden/core discord.js tsyringe reflect-metadatapnpm add -D @warden/console tsx tsup typescript vitest@warden/console is a dev dependency — it hosts the warden binary you use to generate files (make:command, make:event, etc.) and sync commands with Discord (sync, sync:clean). You won’t ship it with your production bot.
Next, create your bootstrap file at src/app.ts:
import {Bot} from '@warden/core';
new Bot() .discover(d => d .interactions('./src/{commands,buttons,modals,menus}/**/*.ts') .events('./src/events/**/*.ts')) .intents(i => i.defaults()) .partials(p => p.defaults()) .start();.discover(...) tells Warden which directories to scan for which kinds of handlers. Each bucket is strict — a stray @event under .interactions(...) will throw at boot. As your bot grows you’ll add .jobs(...) for scheduled work, .hooks(...) for error handlers and lifecycle listeners, and .config(...) for typed config files. See Project structure for the full layout.
You’ll also need a tsconfig.json with decorator support enabled, since Warden relies on TypeScript decorators for auto-discovery:
{ "compilerOptions": { "target": "ES2024", "module": "ESNext", "moduleResolution": "bundler", "experimentalDecorators": true, "emitDecoratorMetadata": true, "strict": true, "esModuleInterop": true, "outDir": "dist", "rootDir": "src", "paths": { "@/*": ["./src/*"] } }, "include": ["src"]}Finally, add these scripts to your package.json:
{ "scripts": { "dev": "tsx watch src/app.ts", "build": "tsup", "start": "node dist/app.js" }}