Features Code
Get Started

Experimental Rust Networking Framework

Small. Sweet.
Protocol-oriented.

Build HTTP/1.1 servers and clients on Tokio today, with symmetric endpoint/outpoint APIs and a core designed for custom protocols. Hotaru 0.8.x is pre-1.0 and under active hardening.

main.rs
use hotaru::http::*;
use hotaru::prelude::*;

LServer!(
    APP = Server::new()
        .binding("127.0.0.1:3003")
        .single_protocol(ProtocolBuilder::new(
            HTTP::server(HttpSafety::default())
        ))
        .build()
);

fn main() {
    run_server!(APP);
}

endpoint! {
    APP.url("/"),
    pub index<HTTP> {
        text_response("Hello, Hotaru!")
    }
}

Current Capabilities

What Hotaru offers today.
Built around a protocol-oriented core.

Opinionated Defaults

The canonical path uses the trans endpoint DSL and automatic registration, with explicit-registration and experimental manual escape hatches.

Protocol-Oriented Core

HTTP/1.1 and HTTPS ship in the main workspace. The Protocol trait is the extension point for custom implementations.

Server-Rendered Web Helpers

Akari templates and optional web middleware support server-rendered Tokio/HTTP applications.

Configurable Request Limits

Configure body, header, line, and method limits through HttpSafety. The 0.8.x HTTP stack remains under active hardening.

Server + Client

Endpoints handle inbound exchanges; outpoints organize outbound work through the same protocol and runtime model.

Typed and Pattern Routing

Literal, typed, regex, wildcard, and catch-all route segments.

Developer Experience

One canonical path.
Explicit alternatives when needed.

Hello World
use hotaru::http::*;
use hotaru::prelude::*;

LServer!(
    APP = Server::new()
        .binding("127.0.0.1:3003")
        .single_protocol(ProtocolBuilder::new(
            HTTP::server(HttpSafety::default())
        ))
        .build()
);

fn main() {
    run_server!(APP);
}

endpoint! {
    APP.url("/"),
    pub index<HTTP> {
        text_response("Hello, Hotaru!")
    }
}
Path Parameters
endpoint! {
    APP.url("/users/<int:id>"),
    pub get_user<HTTP> {
        let user_id = req.param("id")
            .unwrap_or("unknown".to_string());

        akari_json!({
            id: user_id,
            name: "Alice",
            email: "alice@example.com"
        })
    }
}

// GET /users/42 -> {"id":"42","name":"Alice",...}
Akari Templates
endpoint! {
    APP.url("/profile"),
    pub profile<HTTP> {
        akari_render!(
            "profile.html",
            name = "Alice",
            email = "alice@example.com",
            posts = ["First post", "Second post"]
        )
    }
}

// Server-rendered HTML with type-safe templates
Async Middleware
middleware! {
    pub Logger<HTTP> {
        let start = std::time::Instant::now();
        let path = req.path();
        let req = next(req).await?;
        println!("[LOG] {} - {:?}", path, start.elapsed());
        Ok(req)
    }
}

LServer!(APP = Server::new()
    .binding("127.0.0.1:3003")
    .single_protocol(
        ProtocolBuilder::new(HTTP::server(HttpSafety::default()))
            .append_middleware::<Logger>()
    )
    .build());

Try the current
Tokio + HTTP/1.1 path.

Add Hotaru, copy the verified Quickstart above, and run the server locally. Hotaru 0.8.x remains experimental.

cargo add hotaru