| Crates.io | wynd |
| lib.rs | wynd |
| version | 0.11.0 |
| created_at | 2025-03-26 19:28:54.071421+00 |
| updated_at | 2026-01-07 14:31:30.759835+00 |
| description | A simple websocket library for Rust. |
| homepage | |
| repository | https://github.com/guru901/wynd |
| max_upload_size | |
| id | 1606982 |
| size | 233,393 |
A simple, fast, and developer-friendly WebSocket library for Rust.
The easiest way to get started is with the HexStack CLI.
HexStack is a project scaffolding tool (similar to create-t3-app) that lets you spin up new Rust web projects in seconds. With just a few selections, you can choose:
Backend: Wynd, Ripress, or both
Frontend: React, Svelte, or none
Extras: Out-of-the-box WebSocket + HTTP support, and full middleware capability (authentication, logging, etc.)
This means you can quickly bootstrap a real-time full-stack project (Rust backend + modern frontend) or just a backend-only Wynd project.
To create a new project with Wynd:
hexstack new my-project --template wynd
Create a simple echo server:
use wynd::wynd::{Wynd, Standalone};
#[tokio::main]
async fn main() {
let mut wynd: Wynd<Standalone> = Wynd::new();
wynd.use_middleware(|conn, handle, next| async move {
println!("Middleware 1");
if handle.id() % 2 == 0 {
return Err(String::from("Not Authorised"));
} else {
handle.send_text("Hello").await.unwrap();
return Ok(next.call(conn, handle).await.unwrap());
}
});
wynd.use_middleware(|conn, handle, next| async move {
println!("Middleware 2");
Ok(next.call(conn, handle).await.unwrap())
});
wynd.on_connection(|conn| async move {
conn.on_text(|msg, handle| async move {
let _ = handle.send_text(&format!("Echo: {}", msg.data)).await;
});
});
wynd.listen(8080, || {
println!("Server listening on ws://localhost:8080");
})
.await
.unwrap();
}
Wynd supports asynchronous middleware, making it easy to add authentication, logging, rate-limiting, and other cross-cutting concerns. Middleware functions run for every new connection before your event handlers.
Example: Reject unauthenticated users and log connections
wynd.use_middleware(|conn, handle, next| async move {
if !is_authenticated(&handle) {
handle.send_text("Not Authorized").await.unwrap();
return Err("Not Authorized".to_string());
}
println!("Accepted connection from {}", handle.id());
Ok(next.call(conn, handle).await.unwrap())
});
Enable the with-ripress feature to serve both HTTP and WebSocket on the same port:
use ripress::{app::App, types::RouterFns};
use wynd::wynd::{Wynd, WithRipress};
#[tokio::main]
async fn main() {
let mut wynd: Wynd<WithRipress> = Wynd::new();
let mut app = App::new();
wynd.use_middleware(|conn, handle, next| async move {
println!("Middleware for WS+HTTP: Conn ID {}", handle.id());
Ok(next.call(conn, handle).await.unwrap())
});
wynd.on_connection(|conn| async move {
conn.on_text(|event, handle| async move {
let _ = handle.send_text(&format!("Echo: {}", event.data)).await;
});
});
app.get("/", |_, res| async move { res.ok().text("Hello World!") });
app.use_wynd("/ws", wynd.handler());
app.listen(3000, || {
println!("Server running on http://localhost:3000");
println!("WebSocket available at ws://localhost:3000/ws");
})
.await;
}
docs/getting-started.mddocs/api-reference/docs/example/docs/tutorial/docs/guides/We welcome contributions! Please see our Contributing Guide for details.
This project is licensed under the MIT License - see the LICENSE file for details.