# songbird: an async Rust library for the Discord voice API

> Songbird is a Rust library that implements the Discord voice side of a bot, and its most unusual property is that it can be used without either of the usual Rust Discord frameworks, because the gateway and the voice driver are separate features that talk to each other through a connection info value. It needs libopus on the system, it will not give you any codecs beyond Opus unless you add Symphonia yourself, and its release names are birds.

**serenity-rs/songbird** — An async Rust library for the Discord voice API

- Repository: https://github.com/serenity-rs/songbird
- Stars: 527 · Forks: 156
- Language: Rust
- License: ISC
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/serenity-rs-songbird

## A voice library that does not require a Discord framework

Songbird is an async, cross-library compatible voice system for Discord, written in Rust, and it is published on crates.io as songbird with the documentation on docs.rs. The author is Kyle Simpson, the licence is ISC, the edition is 2021, and the minimum supported Rust version is 1.83.0, which the badge in the README links to the Rust release announcement for.

The release naming is a small detail that makes the history easy to read. Version 0.6.1 was published on 2026-10-10, version 0.6.0 carries the name Hoopoe and dates from 2026-04-05, and version 0.5.0 is Starling from 2025-02-21. The default branch is called current rather than main or master, and the repository was last pushed on 2026-10-10.

The structural choice that distinguishes Songbird is that it is not tied to a Discord library. The gateway functionality comes as a feature that is compatible with serenity and with twilight, enabled with the gateway feature together with a serenity or twilight feature and a rustls or native one. The voice driver is a separate feature, the driver one, and it can be used on its own: if you can create a ConnectionInfo using any other gateway, or in any language for your bot, you can run the Songbird voice driver with it. The receive feature adds voice receive and RTP and RTCP packet handling.

That separation is the design. A gateway client speaks to Discord's websocket API, a driver speaks the voice protocol, and the handoff between them is a serialisable connection description. A bot in Python can therefore use a Rust driver, and a Rust bot that already uses twilight can drop Songbird's gateway and keep only the voice half.

## Events, queues, seeking and the shared audio cache

With the gateway and the driver turned on, the default feature set is a full voice system, and the README lists what that includes.

There are events, so the application reacts to track starts, ends and state changes rather than polling. There is a playback queue. There is seeking on compatible streams, which is the one that is conditional, since it depends on the source being able to seek. There are shared multithreaded audio stream caches, which is the part that matters for a bot on a busy server: decoding is expensive, and a cache shared across threads means the same track is not decoded once per voice client.

And there is direct Opus data passthrough from DCA files, which is a shortcut rather than a convenience. A DCA file already contains Opus packets, so they can be forwarded to Discord without being decoded and re-encoded, which removes the largest cost in the pipeline for a bot that plays pre-encoded audio.

The dependency list in the manifest matches this design. The audio path uses rubato for resampling, ringbuf for the ring buffer, discortp for the Discord RTP extensions, opus2 for Opus, and rusty_pool for connection pooling, with flume and dashmap for the concurrency structures and parking_lot for locking. A crypto stack is present as optional dependencies, aes-gcm, chacha20poly1305 and aead, which is the encryption layer of the voice protocol.

The library is also usable in a driverless mode, which the README describes as a way to help manage lavalink sessions. A Lavalink node does the actual audio playback, and a bot using it still needs to know about voice state, so the gateway half of Songbird can be used on its own to keep track of channels and sessions.

## Codecs, and why Symphonia is your problem

The codec story is the part of the documentation that most directly affects what you can play, and it has a trap in it.

Songbird supports all the codecs and formats provided by Symphonia, which is a pure Rust media library, with Opus support provided by opus2, which is an FFI wrapper for libopus. But the README is emphatic about the default: by default Songbird will not request any codecs from Symphonia. To change that, in your own project you need to depend on Symphonia as well.

The manifest example shows both halves of that arrangement:

```toml
# Including songbird alone gives you support for Opus via the DCA file format.
[dependencies.songbird]
version = "0.5"
features = ["builtin-queue"]

# To get additional codecs, you *must* add Symphonia yourself.
# This includes the default formats (MKV/WebM, Ogg, Wave) and codecs (FLAC, PCM, Vorbis)...
[dependencies.symphonia]
version = "0.5"
features = ["aac", "mp3", "isomp4", "alac"] # ...as well as any extras you need!
```

So the default build handles Opus, and Opus is what Discord speaks, which is enough for DCA files and for anything you have already transcoded. Anything else, whether that is an mp3 or a mkv or a wav, needs Symphonia in your own dependency list with the format features you want, and the version you pin has to line up with what Songbird expects.

The alternative, which the README also documents, is to transcode before the bot ever sees the file. The optional yt-dlp dependency, described as an audio and video download tool, is there for exactly that, and it converts the source to the Opus format Discord uses.

## libopus is required, and on Windows it is always built from source

The system dependencies are where a first build goes wrong, and the README is unusually explicit about the requirements.

Opus is the audio codec Discord uses, and it is a required dependency: Songbird cannot work without it. The opus2 crate will use installed libopus binaries if they are available through pkgconf on Linux and macOS, otherwise you need cmake installed to build Opus from source, and that is always the case on Windows. If the library is not installed it will be built for you, but then you need a C compiler and the GNU autotools.

The commands for that are given in the documentation. On Ubuntu, apt install libopus-dev installs the library, and apt install build-essential autoconf automake libtool m4 installs the toolchain; on Arch, pacman -S opus and pacman -S base-devel do the same job.

The second dependency is optional for users and required as a dev-dependency: yt-dlp, or youtube-dl, or similar forks. It is the tool that downloads audio and video from a variety of webpages and converts them to the Opus format Discord uses. The documentation recommends installing youtube-dl with pip, and notes that the installation instructions on the yt-dlp main repository are the place to look for the recommended way to install yt-dlp itself.

So a build needs a C toolchain, which is a real constraint for a pure Rust project, and a Python-adjacent download tool if you want the bot to fetch things from the internet at runtime.

## Intents, the driverless mode, and the rest of the repository

One configuration detail is easy to miss and produces a bot that never joins a channel. Songbird's gateway functionality requires you to specify the GUILD_VOICE_STATES intent, so the voice state events that the gateway needs to see have to be enabled in your bot's privileged intent configuration, not just in the library.

The repository is a normal Rust workspace with a few extras worth knowing. There is an ARCHITECTURE.md, which is the document to read if you want to understand how the gateway, the driver and the tracks relate to each other. There is a CHANGELOG.md with a cliff.toml alongside it, which is the configuration for git-cliff, the tool that generates changelogs from conventional commits. The build is driven by a Makefile.toml, which is the cargo-make format rather than a plain Makefile, and there is a build.rs, which is where the Opus linking logic will be. benches/ holds the benchmarks, and the examples directory has its own Cargo.toml with subdirectories for serenity and for twilight, so the two integration styles are demonstrated side by side rather than in one example with a feature switch.

The remaining structure is assets: images/, resources/, the songbird logo in three formats and a songbird-ico.png. The attribution in the README notes that the logo is based on a copyright free image, a Black-Capped Chickadee by George Gorgas White, which is a pleasant detail and the kind of thing that a project with an ISC licence and an asset licence often has to sort out explicitly.

## What to check before you commit to it

The library is a good fit for a specific kind of project, and the checks are quick.

The first is the build environment. If your CI image is a slim Linux container with no C compiler and no autotools, the build fails or takes a very long time, and the fix is a package install step. If you build on Windows, expect the library to be compiled from source every time, because there is no pkgconf path to a system libopus there.

The second is the codec decision. Decide early whether you need anything beyond Opus. If you only play DCA files or your own transcoded Opus, the default is enough and you avoid depending on Symphonia. If you want to play mp3 or mkv directly, add Symphonia with the right format features and keep the version in step with Songbird's expectation, because the two are separate dependencies with separate version constraints.

The third is the framework question. Songbird's gateway works with serenity and twilight, but the driver does not need either, and a driver driven by a connection info from another language is a legitimate deployment. Pick the split that matches the rest of your bot rather than taking the whole library by default.

The fourth is the intent. If the bot does not join voice channels, check that GUILD_VICE_STATES is set on the bot's privileged intents, because that is a configuration problem outside the library and it looks like a library bug from the inside.

And the fifth is the volume. A bot on a busy server will spend most of its time in the audio path, so the shared multithreaded cache and the Opus passthrough are the two features that decide whether the bot holds up. If your workload is mostly pre-encoded audio, the passthrough path is the one to make sure works first.

## Conclusion

songbird fits a Rust developer who needs voice in a Discord bot and wants to choose their own Discord framework, or none, since the gateway and the driver are separable and the driver can be driven by a connection info produced in another language. It is the wrong tool if you want a batteries included music bot, since streaming sources, queues and playback are yours to assemble from the events and the cache. It is also the wrong tool if you cannot install a C library, because libopus is a hard requirement and on Windows it is built from source. Before you adopt it, install libopus and the autotools first, read ARCHITECTURE.md, and add Symphonia as an explicit dependency if you need anything beyond Opus, because the library will not pull the codecs in for you.

## FAQ

### What is the songbird crate and what does it do?

Songbird is an async Rust library for the Discord voice API. It offers a gateway frontend compatible with serenity and twilight, a standalone voice driver usable with a connection info from any gateway, voice receive with RTP and RTCP packet handling, and by default a full voice system with events, queues, seeking, shared multithreaded audio stream caches and direct Opus passthrough from DCA files.

### What system dependencies does songbird need?

Opus is required, since Songbird cannot work without it, and opus2 will use an installed libopus through pkgconf on Linux and macOS, otherwise you need cmake to build it from source, which is always the case on Windows. Building from source also needs a C compiler and the GNU autotools, installed with apt install build-essential autoconf automake libtool m4 on Ubuntu or pacman -S base-devel on Arch.

### Why does songbird not play mp3 or mkv files out of the box?

By default Songbird will not request any codecs from Symphonia, so you get Opus support through the DCA file format only. To get the other formats and codecs you must add Symphonia as a dependency in your own project, with the format features you need, and keep its version in step with Songbird's.

### Do I need serenity or twilight to use songbird's voice driver?

No. The gateway and the driver are separate features, and the driver can run on its own if you can create a ConnectionInfo using any other gateway, or in any language for your bot. Songbird's own gateway is compatible with serenity and twilight, and can also run driverless to help manage lavalink sessions.

## Sources

- [Issues](https://github.com/serenity-rs/songbird/issues)
- [License: ISC](https://github.com/serenity-rs/songbird/blob/current/LICENSE)
- [README](https://github.com/serenity-rs/songbird/blob/current/README.md)
- [Releases](https://github.com/serenity-rs/songbird/releases)
- [serenity-rs/songbird on GitHub](https://github.com/serenity-rs/songbird)

---

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