# serenity-rs/serenity: a Rust client for the Discord API

> Serenity is a Rust library that wraps the Discord gateway and REST API behind an event handler trait, a shard manager and an optional cache. It is aimed at Rust developers who want to build bots without hand-rolling WebSocket reconnection logic.

**serenity-rs/serenity** — A Rust library for the Discord API.

- Repository: https://github.com/serenity-rs/serenity
- Website: https://discord.gg/serenity-rs
- Stars: 5,619 · Forks: 670
- Language: Rust
- License: ISC
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/serenity-rs-serenity

## What serenity solves for a Rust bot author

Talking to Discord means maintaining a WebSocket to the gateway, reconnecting when it drops, resuming sessions, splitting work across shards as a bot grows, and calling a REST API for everything the gateway does not push. Serenity exists to absorb that. The README describes it plainly as "a Rust library for the Discord API", and the mechanism it offers is a client you configure with a token and a set of gateway intents, then hand an event handler.

The intended audience is a Rust developer building a bot. The README points two kinds of users elsewhere: "To make a bot with slash commands or text commands, see the poise framework built on top of serenity", and for voice, "see the songbird library". That is a deliberate split. Serenity is the transport and model layer; command parsing and voice are separate crates in the same organisation.

## Shards, cache and the event handler trait

The architecture has three moving parts that a user touches directly. The first is the Shard, which the README says is "transparently handled by the library, removing unnecessary complexity", with sharded connections handled automatically. The second is the Cache, which "will be updated automatically for you as data is received from the Discord API via events". When you call a method on a Context, the cache is searched first, which avoids an HTTP round trip.

The third is the handler. You implement a trait, and serenity calls your method when the matching event arrives. The README's example implements EventHandler::message, which fires on Event::MessageCreate. Each handler receives a Context, described as giving information about the event.

Two details in that design are worth flagging. The cache is optional and the feature list warns: "If you are low on RAM, do not enable this." That is an honest trade-off rather than a hidden one. And the Context you receive is not a plain data struct; it carries the HTTP client and the cache, which is why calling a method on it can silently avoid a request.

## Installing serenity and running a ping bot

Serenity is published on crates.io and installed through Cargo. The README gives the dependency block directly. Note that tokio is listed alongside it with the macros and rt-multi-thread features, because the example uses a tokio runtime.

```toml
[dependencies]
serenity = "0.12"
tokio = { version = "1.21.2", features = ["macros", "rt-multi-thread"] }
```

The workspace in the repository also declares rust-version = "1.74" and edition = "2021", so a toolchain older than that will not build it.

A first bot needs three things: a token, the intents that decide which events Discord sends you, and a handler. The README's basic example reads the token from the environment, sets three intents, builds the client and starts a single shard.

```rust
let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let intents = GatewayIntents::GUILD_MESSAGES
    | GatewayIntents::DIRECT_MESSAGES
    | GatewayIntents::MESSAGE_CONTENT;
let mut client =
    Client::builder(&token, intents).event_handler(Handler).await.expect("Err creating client");
if let Err(why) = client.start().await {
    println!("Client error: {why:?}");
}
```

With that running, the handler's message method receives every message the intents allow. The README's handler compares msg.content to "!ping" and replies through msg.channel_id.say(&ctx.http, "Pong!"). If you send !ping in a channel the bot can see, and MESSAGE_CONTENT is among your intents, you get Pong! back. Drop MESSAGE_CONTENT and the content field will not carry what you expect, which is a common first failure.

The repository ships a numbered examples directory covering more ground than the README: e01_basic_ping_bot, e05_command_framework, e10_collectors, e14_slash_commands, e16_sqlite_database and e19_interactions_endpoint among others. Those are the practical next step after the ping bot.

## Feature flags are the real configuration surface

Serenity does not ship one binary shape. Cargo features decide what is compiled in, and the defaults are broad: builder, cache, chrono, client, framework, gateway, http, model, standard_framework, utils and rustls_backend. To trim that, you disable defaults and name what you want.

```toml
[dependencies.serenity]
default-features = false
features = ["pick", "your", "feature", "names", "here"]
version = "0.12"
```

The README offers two alternative default sets for the TLS question: default_native_tls swaps rustls_backend for native_tls_backend, and default_no_backend excludes a backend entirely so you pick your own. Its own advice is blunt: "If you are unsure which to pick, use the default features by not setting default-features = false."

Two entries in the feature list deserve attention before you plan a bot. standard_framework is marked "Deprecated as of v0.12.1" with poise recommended instead, so building new commands on it is a dead end. And voice "Enables registering a voice plugin to the client", not voice itself; the README names lavalink-rs or Songbird as the plugins to use. There is also unstable_discord_api, which the README describes as enabling Discord API features that are not stable, and tokio_task_builder, which requires RUSTFLAGS="--cfg tokio_unstable" to spawn named tasks.

## MSRV policy and what it costs you

The minimum supported Rust version is 1.74, and the policy is branch-specific. On the current branch, MSRV is held stable between minor releases. The next branch tracks the latest Rust release instead, so it can move. When a major release is cut, the MSRV on current is updated to match next and is then supported until the following major release.

That is a reasonable arrangement, but the README admits a hole in it: "Occasionally, dependencies may violate SemVer and update their own MSRV in a breaking way. As a result, pinning their versions will become necessary to successfully build Serenity using an older Rust release." In other words, the promise covers serenity's own code, not its dependency tree. If you are pinned to an old toolchain, expect to pin transitive crates too.

The upgrade cost is visible in the release history. v0.12.3 and v0.12.4 landed two days apart in November 2024, and v0.12.5 followed in December 2025. The CHANGELOG.md at the repository root is where the actual breaking changes are recorded; the README does not document a migration path between minor versions.

## Licence and what the ISC terms mean in practice

Serenity is licensed under ISC, declared both in the Cargo.toml workspace package section and in LICENSE.md at the repository root. ISC is a short permissive licence in the same family as MIT and BSD: it permits use, modification and redistribution provided the copyright notice and permission notice are retained.

The practical consequence for a bot author is that shipping a closed-source bot built on serenity is not blocked by the library's own terms. This is not legal advice, and the licence text is short enough to read in full. One thing to check yourself: the ISC grant covers serenity, not the crates it depends on. The dependency list includes rustls, tokio and others with their own licences, and if you distribute a binary you are carrying all of them.

## Conclusion

Adopt serenity if you are writing a Discord bot in Rust and want the gateway, sharding and an optional cache handled for you, and if Rust 1.74 or newer is acceptable. Do not adopt it if you need voice out of the box (the voice feature only registers a plugin and points at Songbird or lavalink-rs) or if you want a command framework that is not deprecated, in which case use poise. Before committing, check the feature list against your RAM budget and confirm the MSRV on the branch you are tracking.

## FAQ

### What is serenity-rs/serenity?

It is a Rust library for the Discord API, published on crates.io as serenity. It provides a client that handles gateway shards, an optional cache, and an EventHandler trait you implement to receive events.

### How do I install serenity in a Rust project?

Add serenity = "0.12" to the dependencies in Cargo.toml, along with tokio with the macros and rt-multi-thread features as the README's example does. The workspace declares rust-version = "1.74", so an older toolchain will not build it.

### Does serenity handle sharding automatically?

Yes. The README states that the Shard is transparently handled by the library and that sharded connections are handled automatically. The client is described as a manager for shards and event handlers.

### Is the standard_framework feature still usable in serenity?

It is present but marked deprecated as of v0.12.1, and the README recommends using the poise framework instead. The framework feature itself remains in the default set.

### Does serenity support voice channels?

Not on its own. The voice feature only registers a voice plugin with the client, and the README recommends lavalink-rs or Songbird as the plugins that handle actual voice connections.

## Sources

- [License: ISC](https://github.com/serenity-rs/serenity/blob/current/LICENSE)
- [Project website](https://discord.gg/serenity-rs)
- [README](https://github.com/serenity-rs/serenity/blob/current/README.md)
- [Releases](https://github.com/serenity-rs/serenity/releases)
- [serenity-rs/serenity on GitHub](https://github.com/serenity-rs/serenity)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/serenity-rs-serenity
