Composure
Discord bots that live on the edge.
Slash commands, buttons, modals and rich Components V2 layouts, written once in Rust and served from Cloudflare Workers or any server. No gateway, no idle process, no bill while nobody is talking to your bot.
Guide · API docs · Examples · Discord · Crates
use ;
/// Give someone a cookie
;
The function is the command. Its parameters become Discord Options (with min/max
enforced by Discord and checked against u8 at compile time), its doc comment the description,
its return value the reply. Hand Bot to an Adapter to serve it, and to composure_sync to
register it.
Why Composure?
Composure handles Interactions only: commands, buttons, selects and modals that Discord delivers to your bot as signed HTTP requests.
- Serverless. No WebSocket to keep alive, no process to babysit. Deploy to Cloudflare Workers and pay per request, or run it on any box with tokio.
- Written once. One function per command: the definition Discord stores and the handler that answers come from the same code, so they can never drift apart.
- Typed end to end. Options arrive as
&str,u8,&User,Roleor your own enums. Duplicate commands, too many Options, out-of-range bounds and badcustom_idprefixes fail to compile, not in production. - Markup for messages. Build Components V2 messages and modals with JSX-like
rsx!, with click handlers right next to the buttons they belong to. - State in the
custom_id. Button and modal state is encoded into thecustom_idfor you, so a counter needs no database. - Small and fast. A few microseconds and a few dozen allocations per Interaction; the full example bot is about 307 KB of gzipped WASM. The core has no async runtime and no HTTP stack.
- REST and more. A REST client for every Discord endpoint, deferred responses with
background work, follow-ups, file uploads, Webhook Events,
tracing, and a command sync CLI with CI drift checks.
| Gateway bot | Composure | |
|---|---|---|
| Connection | A WebSocket, always open | None: Discord calls you |
| Hosting | A server running 24/7 | Cloudflare Workers, a container, any server |
| Scales to zero | No | Yes |
| Commands defined | Often twice (registration + handler) | Once, as a function |
| Reads every message | Possible (with intents) | No: Interactions and Webhook Events only |
If your bot needs to watch every message or presence update, use a gateway library. If it only answers people, Composure needs no gateway connection, and on Workers no server at all.
A tour
Rich messages with rsx! and #[view]
use ;
/// A card that counts its likes. The count lives in the button's custom_id.
Clicking Like re-renders the message with new Props. Every Discord component has a tag, and every tag's attributes are documented.
Typed modal forms
use ;
Slow work with defer
use Duration;
use ;
/// Crunch some numbers
Serve it
// Cloudflare Workers
async
// Any server
async
Sync it
Quick start
Or start from a template, with a Command, a Sync binary, a test, and the platform's
configuration (a Dockerfile for tokio):
Then follow Getting started: it takes you from an empty crate to a deployed bot.
Crates
| Crate | ||
|---|---|---|
composure |
The core: types, the handler runtime, the REST client, and the macros (macros feature) |
|
composure_adapter_cloudflare |
Serve on Cloudflare Workers | |
composure_adapter_tokio |
Serve from a server on tokio and hyper | |
composure_sync |
Register your commands with Discord at deploy time | |
composure_macros |
The macros, re-exported by composure |
|
composure_commands |
A builder for command definitions, without the macros |
Everything optional is behind a feature flag (REST endpoints per resource, tracing, Web
Crypto signature checks), so a Worker only ships what it uses. See
feature flags.
Learn more
- The guide: commands, responses, components and modals, Views and styling, REST and deferring, Webhook Events, platforms, testing. Every example in it is compiled and tested.
- Examples: one bot using every feature, served on Workers and on tokio.
- The Composure bot:
Composure's own bot on Workers, a real deployment. Add it to get release announcements in
your server (
/notify setup), read the changelog (/changelog) and search these docs (/docs);/invitein any server it's in gives the install links. - Design decisions and the glossary.
Status
Composure is pre-1.0: the API may change between minor versions. It tracks Discord's v10 API and its latest components (Components V2, labels, radio groups, checkboxes, file uploads). Issues and pull requests are welcome, and questions go in the Discord server.
Contributing
See CONTRIBUTING.md for
the development setup and how releases work: each pull request adds a change file
(knope document-change), and merging the generated release PR publishes every crate. Every
version is in the changelog.
License
Licensed under the Apache License, Version 2.0.