Skip to main content

Crate tachyon_web

Crate tachyon_web 

Source
Expand description

§Tachyon-Web

A clean, highly optimized, multi-protocol web framework for Rust.

tachyon-web follows the philosophy of an Axum-compatible API, but takes a simpler, more unified approach to high-performance transport protocols. Where other frameworks require complex configurations and separate crates to handle modern protocols, tachyon-web provides a seamless, unified experience out-of-the-box for HTTP/1.1, HTTP/2, and HTTP/3, as well as automatic Let’s Encrypt TLS certificate management.

§Design philosophy

  1. Axum-like simplicity: Build a Router, chain .route() calls, and use type-safe extractors (Path, Query, Json, State) in handler functions — the same ergonomic patterns you already know.

  2. Drop-in replacement for Axum workloads: Most axum handlers compile against tachyon-web without modification. The main incompatibility is Tower middleware layers, which Tachyon does not use — by design, to eliminate the overhead Tower introduces.

  3. Effortless TLS, HTTP/2, and HTTP/3: Starting a TLS server is a single call. Let’s Encrypt integration is built-in — no CLI tools, no shell scripts, no cron jobs. Certificates are automatically issued, cached to disk, and hot-reloaded on renewal.

  4. High Performance: Built natively on hyper and s2n-quic, tachyon-web prioritizes minimal allocations, lock-free hot paths, and direct socket handling.

§Quick start: Plain HTTP

use tachyon_web::{Router, Server, get};
use tachyon_web::http::response::Html;
use tokio::net::TcpListener;

async fn hello_world() -> Html<&'static str> {
    Html("<h1>Hello from Tachyon-Web!</h1>")
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let app = Router::new()
        .route("/", get(hello_world));

    let listener = TcpListener::bind("0.0.0.0:8080").await?;
    Server::new(app).serve_http(listener).await?;
    Ok(())
}

§HTTPS with automatic Let’s Encrypt certificates

Call Server::serve_all_acme to get fully automatic certificate management:

  • Issues a certificate from Let’s Encrypt on first startup.
  • Serves ACME HTTP-01 challenges in-process (no separate server or Certbot required).
  • Saves credentials and the certificate to disk — safe across restarts.
  • Renews automatically 30 days before expiry with exponential-backoff retries.
  • Hot-swaps the certificate in the TLS stack with zero downtime.
use tachyon_web::{Router, Server, get};

async fn hello() -> &'static str { "Hello, secure world!" }

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    #[cfg(feature = "lets-encrypt")]
    {
        let app = Router::new().route("/", get(hello));

        Server::new(app)
            .serve_all_acme(
                "0.0.0.0:443",                   // HTTPS / HTTP/2 / HTTP/3
                "0.0.0.0:80",                    // HTTP redirect + ACME challenges
                vec!["example.com".to_string()], // domains (must resolve to this server)
                "admin@example.com".to_string(), // Let's Encrypt contact email
                "/var/cache/tachyon/certs",      // persistent cert cache (survives restarts)
                false,                           // false = production LE, true = staging
            )
            .await?;
    }
    Ok(())
}

§HTTPS with a pre-loaded certificate (self-signed or CA-issued)

For development or when you manage certificates externally:

use tachyon_web::{Router, Server, get};

async fn hello() -> &'static str { "secure hello" }

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    #[cfg(feature = "cert-gen")]
    {
        use tachyon_web::tls;

        let app = Router::new().route("/", get(hello));

        // Generate an ephemeral self-signed cert (for development only).
        let cert = tls::generate_self_signed_cert(vec!["localhost".to_string()])?;

        Server::new(app)
            .start_all(
                "0.0.0.0:443",
                Some("0.0.0.0:80"),  // optional HTTP → HTTPS redirect
                cert.cert_pem,
                cert.key_pem,
            )
            .await?;
    }
    Ok(())
}

§Native Tor .onion hidden services

With the tor feature, Server::serve_tor publishes the app directly as a v3 Tor hidden service — via arti-client/tor-hsservice — with no external tor daemon or reverse proxy required:

use tachyon_web::{Router, Server, get};

async fn hello() -> &'static str { "Hello from an onion service!" }

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    #[cfg(feature = "tor")]
    {
        let app = Router::new().route("/", get(hello));
        Server::new(app).serve_tor("my-hidden-service").await?;
    }
    Ok(())
}

§Native I2P .b32.i2p eepsites

With the i2p feature, Server::serve_i2p publishes the app directly as an I2P eepsite — via the vendored, statically-linked libi2pd router — with no external i2pd/Java-I2P process required:

use tachyon_web::{Router, Server, get};

async fn hello() -> &'static str { "Hello from an eepsite!" }

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    #[cfg(feature = "i2p")]
    {
        let app = Router::new().route("/", get(hello));
        Server::new(app).serve_i2p("my-eepsite").await?;
    }
    Ok(())
}

⚠️ Unlike every other feature in this crate, i2p pulls in a dependency that itself contains unsafe code — the #![forbid(unsafe_code)] below still holds for tachyon-web’s own source (it cannot be locally overridden by any feature), but it says nothing about the FFI boundary this feature links in. libi2pd is a C++ library with no stable C ABI, so supporting it at all requires an unsafe FFI boundary — one written for this project (i2pd-sys/tachyon-i2p), not a long-established independently-audited pure-Rust dependency the way arti-client is for tor. See server::i2p for the full disclosure before enabling this in anything security-sensitive.

Re-exports§

pub use http::error::Error;
pub use http::error::Result;
pub use http::response;
pub use http::response::AppendHeaders;
pub use http::response::Html;
pub use http::response::IntoResponse;
pub use http::response::IntoResponseParts;
pub use http::response::Redirect;
pub use http::response::ResponseParts;
pub use routing::extract;
pub use routing::extract::Cookies;
pub use routing::extract::Form;
pub use routing::extract::Json;
pub use routing::extract::OriginalUri;
pub use routing::extract::Query;
pub use routing::extract::ConnectInfo;
pub use routing::extract::Extension;
pub use routing::extract::FromRef;
pub use routing::extract::FromRequest;
pub use routing::extract::FromRequestParts;
pub use routing::extract::Host;
pub use routing::extract::Path;
pub use routing::extract::RawQuery;
pub use routing::extract::State;
pub use routing::handler::BoxedFuture;
pub use routing::handler::BoxedHandler;
pub use routing::handler::Handler;
pub use routing::middleware::MiddlewarePosition;
pub use routing::middleware::Next;
pub use routing::static_dir::ServeDir;
pub use routing::MethodRouter;
pub use routing::Router;
pub use routing::RouterError;
pub use routing::any;
pub use routing::connect;
pub use routing::delete;
pub use routing::get;
pub use routing::head;
pub use routing::options;
pub use routing::patch;
pub use routing::post;
pub use routing::put;
pub use routing::trace;
pub use server::HttpsServer;
pub use server::RustlsConfig;
pub use server::bind_rustls;
pub use server::MultiServer;
pub use server::Server;
pub use server::serve;

Modules§

anonymity
Opt-in response hardening for .onion/.i2p routes — see anonymity_guard.
http
HTTP constructs like error types and response helpers.
routing
Axum-compatible Routing and Handler traits.
server
High-performance Web Server Engine supporting HTTP/1.1, HTTP/2, and HTTP/3.
tls
TLS helper utilities.
ws
WebSocket support (RFC 6455), mirroring Axum’s extract::ws API.