
Async - Community
This project is under the GNU GPL v3 license
All the projects in the AsyncCommunityDiscord organisation are used by the discord server discord.gg/graven both by the moderators and the members.
Most of the contributors are part of the staff but the members are also allowed to contribute.
OmniBot is a modular Discord bot: each feature is a self-contained module
that is auto-discovered at startup and can be installed/uninstalled per Discord
server via /modules. Modules declare their own slash commands, event
listeners, interaction handlers and a typed configuration schema (edited live
with /config <module>) — the core wires everything together, so adding a
feature never means touching the bootstrap.
| Area | Choice |
|---|---|
| Language | TypeScript (ESM, NodeNext), Node.js 24 |
| Discord | discord.js v14 |
| Database | PostgreSQL 17 via Prisma (multi-file schema) |
| Package mgr | pnpm |
| Toolchain | mise (tool versions), oxlint + oxfmt (lint/format), lefthook (git hooks), commitlint (commit messages) |
| Tests | Vitest |
| Logging | pino |
| Dev runner | pitchfork (one-command stack) |
- mise — pins Node.js, pnpm and pitchfork (
mise install). Without mise, install Node.js 24 and pnpm manually (versions are in.mise.toml). - Docker (for the PostgreSQL container).
- A Discord bot token — from the Discord Developer Portal.
mise install # installs Node, pnpm, pitchfork from .mise.toml
pnpm install # installs dependencies and git hooks (lefthook)
cp .env.example .env # then fill in the values (see Environment below)One command brings up PostgreSQL and the bot (daemons defined in pitchfork.toml):
pitchfork start bot # starts the db daemon, waits until it is ready, then runs the bot
pitchfork logs bot # tail logs · pitchfork stop bot db # stop everythingPrefer to run things yourself?
docker compose up -d # PostgreSQL 17
pnpm prisma:migrate # apply migrations (first run)
pnpm dev # run the bot with tsxCopy .env.example to .env:
DISCORD_TOKEN— bot token from the Discord Developer Portal.DATABASE_URL— PostgreSQL connection string (default matchescompose.yaml).DEV_GUILD_ID— dev only: guild where slash commands are registered instantly (global commands take ~1h to propagate). Required bypnpm dev.
src/
├── core/ # framework: module loader, /config & /modules, command/event/interaction loaders
├── modules/ # one folder per feature module (commands/, listeners/, services/, *.config.ts, *.module.ts)
├── lib/ # shared contracts (module, config, registry, listener, …)
└── prisma/ # consolidated schema + migrations (generated — never edit by hand)
Each module is a plugin: drop a folder under src/modules/ and it is discovered
automatically — no registration anywhere else.
pnpm dev # run with tsx
pnpm build # prisma:generate + tsc → dist/
pnpm test # run the full test suite (unit + integration)
pnpm format # oxfmt + oxlint --fix
pnpm prisma:migrate # create & apply a migration
pnpm prisma:studio # open Prisma StudioContributions are welcome — staff and members alike.
- Start with the developer guide in
docs/: how to create a module, slash commands, listeners, interactions, services, the Prisma schema, and the user-facing behaviour. - Conventional Commits are enforced (commitlint, via a lefthook
commit-msghook). A lefthookpre-commithook runs oxfmt + oxlint on staged files —pnpm installsets the hooks up for you. - Before opening a PR, make sure
pnpm build,pnpm test,pnpm exec oxlint --deny-warningsandpnpm exec oxfmt --checkall pass (CI runs the same). - Agent instructions live in
AGENTS.md(also symlinked asCLAUDE.md) — a concise orientation that is handy for humans too. - Known tech-debt and follow-ups are tracked in
AUDIT.md.