Skip to content

create-@warden

The fastest way to create a new Warden project is with the create-@warden scaffolder. One command gives you a fully configured project with working examples, tooling, and sensible defaults — so you can focus on building your bot instead of configuring build tools.

Terminal window
pnpm create @warden my-mod-bot

You can also use npm or yarn if you prefer:

Terminal window
npx create-@warden my-mod-bot
yarn create @warden my-mod-bot

The scaffolder takes one positional argument — the project name — and a single --force flag for overwriting an existing directory. Everything else is built-in: every first-party plugin, a working bot with mini-apps, drizzle schema, seeders, console commands, the lot. Nothing is opt-in.

This is a deliberate change from earlier versions. The interactive “do you want a database / cache / localization?” flow led to half-wired projects that needed manual stitching the moment a feature was added later. The scaffolder now ships everything and trusts you to delete what you don’t want — rm -rf src/lang/ is faster than wiring i18n in by hand three months later.

The scaffolder copies a full starter project — every primitive Warden ships gets a working example:

my-mod-bot/
src/
bootstrap.ts # shared Bot — plugins + config discovery
app.ts # Discord runtime entry
cli.ts # console kernel entry
commands/
PingCommand.ts
tasks/ # tasks mini-app (commands + buttons + repository)
polls/ # polls mini-app
mod/ # moderation mini-app
context/
UserInfoContext.ts # user context menu
buttons/
tasks/, polls/, mod/ # button handlers with dynamic custom IDs
modals/
FeedbackModal.ts # modal handler with typed fields
menus/
polls/PollVoteMenu.ts # string-select menu
events/
ReadyEvent.ts
MemberJoinEvent.ts # decomposed event example
MemberBoostEvent.ts
errors/
FallbackErrorHandler.ts
lifecycle/
LogOnErrorLifecycle.ts
jobs/ # empty, ready for scheduled work
middleware/
AdminOnly.ts # typed middleware
LogRequests.ts # global middleware
repositories/ # query layers per mini-app
db/
schema/ # drizzle schema
types.ts # pinned `Db` alias for inference
seeders/ # picked up by cli.ts via .load()
config/ # typed config per plugin
lang/ # i18n translations
tests/ # vitest tests for the scaffolded examples
.env.example
.env
docker-compose.yml
drizzle.config.ts
eslint.config.js
.prettierrc
tsconfig.json
tsup.config.ts
vitest.config.ts
package.json

Every generated file is a working example, not a placeholder. The commands run, the events fire, the error handler catches exceptions, and the tests pass. You can start building immediately by modifying the examples or generating new files with the make commands.

The starter’s bootstrap is split across two files. src/bootstrap.ts constructs the shared Bot — plugins and config discovery — and exports it as the default. Both src/app.ts (Discord runtime) and src/cli.ts (console kernel) import that singleton and add what’s specific to their entry point. Your first bot walks through the full pattern.

Once the scaffolder has finished, you’re a few commands away from a running bot:

  1. Install dependencies:

    Terminal window
    cd my-mod-bot
    pnpm install
  2. Start the Docker services (database, cache):

    Terminal window
    docker-compose up -d
  3. Configure your .env file with your Discord bot token and application ID (the scaffolder creates the file, you just need to fill in the values):

    DISCORD_TOKEN=your-bot-token
    DISCORD_APPLICATION_ID=your-application-id
  4. Run the initial migration:

    Terminal window
    pnpm db:migrate
  5. Start the development server:

    Terminal window
    pnpm dev

Your bot is online. Head to your Discord server and try /ping. From here, check out Your First Bot for a guided walkthrough, or jump straight to generating new files with the make commands.