Back to rankings

Totodore/socketioxide

Rustdocs.rs/socketioxide

A socket.io server implementation in Rust that integrates with the Tower ecosystem and the Tokio stack.

hyperrustsocket-iotokioaxumtower
Star Growth
Stars
1.6k
Forks
80
Weekly Growth
Issues
12
5001k1.5k
Apr 2023May 2024Jun 2025Jul 2026
Artifactscrates.iocargo add socketioxide
README

Socketioxide 🚀🦀

Shows Anuraghazra's GitHub Stats.

A socket.io server implementation in Rust that integrates with the Tower ecosystem and the Tokio stack. It integrates with any server framework based on tower like Axum, Warp, Salvo, Viz or Hyper. Add any other tower based middleware on top of socketioxide such as CORS, authorization, compression, etc with tower-http.

Crates.io Documentation CI

Features

Examples

Chat app 💬 (see full example here)
io.ns("/", |s: SocketRef| {
    s.on("new message", |s: SocketRef, Data::<String>(msg)| {
        let username = s.extensions.get::<Username>().unwrap().clone();
        let msg = Res::Message {
            username,
            message: msg,
        };
        s.broadcast().emit("new message", msg).ok();
    });

    s.on(
        "add user",
        |s: SocketRef, Data::<String>(username), user_cnt: State<UserCnt>| {
            if s.extensions.get::<Username>().is_some() {
                return;
            }
            let num_users = user_cnt.add_user();
            s.extensions.insert(Username(username.clone()));
            s.emit("login", Res::Login { num_users }).ok();

            let res = Res::UserEvent {
                num_users,
                username: Username(username),
            };
            s.broadcast().emit("user joined", res).ok();
        },
    );

    s.on("typing", |s: SocketRef| {
        let username = s.extensions.get::<Username>().unwrap().clone();
        s.broadcast()
            .emit("typing", Res::Username { username })
            .ok();
    });

    s.on("stop typing", |s: SocketRef| {
        let username = s.extensions.get::<Username>().unwrap().clone();
        s.broadcast()
            .emit("stop typing", Res::Username { username })
            .ok();
    });

    s.on_disconnect(|s: SocketRef, user_cnt: State<UserCnt>| {
        if let Some(username) = s.extensions.get::<Username>() {
            let num_users = user_cnt.remove_user();
            let res = Res::UserEvent {
                num_users,
                username: username.clone(),
            };
            s.broadcast().emit("user left", res).ok();
        }
    });
});
Echo implementation with Axum 🏓
use axum::routing::get;
use serde_json::Value;
use socketioxide::{
    extract::{AckSender, Bin, Data, SocketRef},
    SocketIo,
};
use tracing::info;
use tracing_subscriber::FmtSubscriber;

fn on_connect(socket: SocketRef, Data(data): Data<Value>) {
    info!("Socket.IO connected: {:?} {:?}", socket.ns(), socket.id);
    socket.emit("auth", data).ok();

    socket.on(
        "message",
        |socket: SocketRef, Data::<Value>(data), Bin(bin)| {
            info!("Received event: {:?} {:?}", data, bin);
            socket.bin(bin).emit("message-back", data).ok();
        },
    );

    socket.on(
        "message-with-ack",
        |Data::<Value>(data), ack: AckSender, Bin(bin)| {
            info!("Received event: {:?} {:?}", data, bin);
            ack.bin(bin).send(data).ok();
        },
    );
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    tracing::subscriber::set_global_default(FmtSubscriber::default())?;

    let (layer, io) = SocketIo::new_layer();

    io.ns("/", on_connect);
    io.ns("/custom", on_connect);

    let app = axum::Router::new()
        .route("/", get(|| async { "Hello, World!" }))
        .layer(layer);

    info!("Starting server");

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();

    Ok(())
}
Other examples are available in the example folder

Contributions and Feedback / Questions

Any contribution is welcome, feel free to open an issue or a PR. If you want to contribute but don't know where to start, you can check the issues.

If you have any question or feedback, please open a thread on the discussions page.

License 🔐

This project is licensed under the MIT license.

Related repositories
vercel/hyper

A terminal built on web technologies

TypeScriptnpmMIT Licenseterminaljavascript
hyper.is
44.7k3.6k
hyperium/hyper

An HTTP library for Rust

Rustcrates.ioMIT Licenserusthyper
hyper.rs
16.2k1.8k
bnb/awesome-hyper

🖥 Delightful Hyper plugins, themes, and resources

Creative Commons Zero v1.0 Universalhyperhyperterm
11k375
xonsh/xonsh

🐚 Python-powered shell. Full-featured, cross-platform and AI-friendly.

PythonPyPIOtherxonshdevops
xon.sh
9.6k730
enquirer/enquirer

Stylish, intuitive and user-friendly prompts. Used by eslint, webpack, yarn, pm2, pnpm, RedwoodJS, FactorJS, salesforce, Cypress, Google Lighthouse, Generate, tencent cloudbase, lint-staged, gluegun, hygen, hardhat, AWS Amplify, GitHub Actions Toolkit, @airbnb/nimbus, and more! Please follow Enquirer's author: https://github.com/jonschlinkert

JavaScriptnpmMIT Licensepromptinquirer
github.com/jonschlinkert
7.9k298
mjswensen/themer

🎨 themer takes a set of colors and outputs themes for your apps (editors, terminals, wallpapers, and more).

TypeScriptnpmMIT Licensewallpapersthemer
themer.dev
5.8k136
daltonmenezes/aura-theme

✨ A beautiful dark theme for your favorite apps.

TypeScriptnpmMIT Licensevscodetheme
3.8k184
AutomatedLab/AutomatedLab

AutomatedLab is a provisioning solution and framework that lets you deploy complex labs on HyperV and Azure with simple PowerShell scripts. It supports all Windows operating systems from 2008 R2 to 2022, some Linux distributions and various products like AD, Exchange, PKI, IIS, etc.

PowerShellMIT Licensepowershelldeployment
2.2k387
sindresorhus/hyper-snazzy

Elegant Hyper theme with bright colors

JavaScriptnpmMIT Licensehyperhyper-theme
1.5k72
klaudiosinani/hyper-pokemon

Tailor-made Pokémon themes for your Hyper terminal

JavaScriptnpmMIT Licensepokemonhyper
klaudiosinani.com/hyper-pokemon
1.2k73
onmyway133/FinderGo

🐢 Open terminal quickly from Finder

SwiftOtherfindersync
onmyway133.com
1.2k70