twilight-gateway is an implementation of a client over Discord's websocket gateway.

The main type is the Shard: it connects to the gateway, receives messages, parses and processes them, and then gives them to you. It will automatically reconnect, resume, and identify, as well as do some additional connectivity checks.


twilight-gateway includes a number of features for things ranging from payload deserialization to TLS features.


twilight-gateway supports serde_json and simd-json for deserializing and serializing events.


The simd-json feature enables usage of simd-json, which uses modern CPU features to more efficiently deserialize JSON data. It is not enabled by default.

In addition to enabling the feature, you will need to add the following to your <project_root>/.cargo/config:

rustflags = ["-C", "target-cpu=native"]


twilight-gateway has features to enable tokio-websockets' TLS features. These features are mutually exclusive. rustls-native-roots is enabled by default.


The native-tls feature enables tokio-websockets' native-tls feature.


RusTLS allows specifying from where certificate roots are retrieved from.

Native roots

The rustls-native-roots feature enables tokio-websockets' rustls-native-roots feature.

This is enabled by default.

Web PKI roots

The rustls-webpki-roots feature enables tokio-websockets' rustls-webpki-roots feature.



The zlib-stock feature makes flate2 use of the stock Zlib which is either upstream or the one included with the operating system.


zlib-simd enables the use of zlib-ng which is a modern fork of zlib that in most cases will be more effective. However, this will add an external dependency on cmake.

If both are enabled or if the zlib feature of flate2 is enabled anywhere in the dependency tree it will make use of that instead of zlib-ng.


Starting a Shard and printing the contents of new messages as they come in:

use std::{env, error::Error};
use twilight_gateway::{EventTypeFlags, Intents, Shard, ShardId, StreamExt as _};

async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
    // Initialize the tracing subscriber.

    let token = env::var("DISCORD_TOKEN")?;
    let intents = Intents::GUILD_MESSAGES;
    let mut shard = Shard::new(ShardId::ONE, token, intents);
    tracing::info!("created shard");

    while let Some(item) = shard.next_event(EventTypeFlags::all()).await {
        let Ok(event) = item else {
            tracing::warn!(source = ?item.unwrap_err(), "error receiving event");


        tracing::debug!(?event, "event");