The Hotaru 0.8 era starts from 23/May/2026.
Small, sweet, easy framework with a protocol-neutral, no_std-ready core
Official Website | Example Project
Repository transfer notice: the Hotaru repository has moved to
https://github.com/Field-of-Dream-Studio/hotaru.
MSRV: 1.88
The tokio + HTTP stack (default features trans, http, tokio) is the tested, supported path and is safe for production use today.
Everything else is experimental and will stabilize by 0.8.7:
RuntimeSpectrait surface (hotaru_rt_tokiois the supported default;hotaru_rt_embassyis experimental)no_stdbuilds ofhotaru_core(Cortex-M / RISC-V bare-metal, CI-verified and connected to experimental embedded backend crates, but not yet production-validated on hardware)- IO adapter crates:
hotaru_io_futuresships as a standalone crate (limited real-world use).hotaru_io_embeddedlives in the workspace and is still experimental and unpublished (crates.io). Thehotarufacade exposesEmbeddedIothrough its optionalio_embeddedfeature. - Embassy runtime backend (
hotaru_rt_embassy, experimental)
If you are shipping something now, stick with the tokio default and revisit the experimental paths as they land.
- Multi-Protocol: HTTP/1.1 and HTTPS (TLS) ship out of the box. The
Protocoltrait is an open extension point for custom TCP-based protocols (WebSocket, MQTT, and other frames), though no non-HTTP protocol ships in this workspace today - Server + Client: Endpoints for inbound traffic, outpoints for outbound. Same protocol trait, same routing, same middleware
- Runtime-Neutral Core:
hotaru_corespeaks to any async runtime through theRuntimeSpectrait. Tokio ships today viahotaru_rt_tokio; other runtimes can plug in via the same sibling-crate pattern. IO adapters are further along, withhotaru_io_tokio,hotaru_io_futures, and the experimental in-workspacehotaru_io_embedded no_std-Ready Core:hotaru_corebuilds bare-metal on Cortex-M4/M7 and RISC-V (with atomics) underalloc. CI verified onthumbv7em-none-eabihfandriscv32imac-unknown-none-elf- Sync main:
fn main() { run_server!(APP); }. Noasync fn main, no#[tokio::main] - Ergonomic Macros:
endpoint!/outpoint!/middleware!DSL in three flavors (trans,semi-trans,attr) - Full-Stack: Akari template rendering, form/URL-encoded body parsing, session cookies, HTTP body compression (gzip / deflate / brotli / zstd) all built in
- Flexible Routing: Regex, literal, and pattern segments (
<int:id>,<uuid:token>,<**path>) with a tree walker
use hotaru::prelude::*;
use hotaru::http::*;
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!")
}
}run_server!(APP) builds a tokio runtime, blocks the current thread, and shuts down on Ctrl+C. No async fn main, no #[tokio::main]. See Core Concepts for the sibling macros (run_server_until!, run_server_no_block!, run_server_no_block_until!) when you need a custom stop source or multi-server orchestration.
Install the Hotaru CLI tool:
cargo install hotaruCreate a new project:
hotaru new my_app
cd my_app
cargo runAdd to your Cargo.toml:
[dependencies]
hotaru = "0.8.3"
tokio = { version = "1", features = ["full"] }Default features: trans, http, tokio. Cargo's additive feature unification means sub-features pull in their prerequisites automatically — you never have to enable a base feature by hand.
Protocol stack
http(default-on): HTTP/1.1 stack (hotaru_http+ahttpm). Opt out withdefault-features = falsefor protocol-only builds (e.g. gRPC-only deployments) —hotaru::http::*,HTTP,HttpContext,HttpRequest,HttpResponse, etc. then disappear from the crate surface.tokio(default-on): Tokio runtime + TCP/IO defaults for the umbrella crate (Server,Client,Url,S*aliases,TcpTransport,TokioRuntime). If you disable default features but still use those defaults, re-enabletokio.https: TLS/HTTPS support — surfacesHTTPS,TlsTransport,TlsOutboundTarget,TlsClientConfig. Implieshttp.http_compression: HTTP body codecs forContent-Encoding(gzip / deflate / brotli / zstd). Off by default becausebrotli+zstdtogether add ~7 s to a clean build. Implieshttp. Without this feature,ContentCoding::decode_compressed/encode_compressedreturnio::ErrorKind::Unsupportedfor compressed bodies.
Endpoint macro flavor — pick one (see Core Concepts):
trans(default) — bang macro with hotaru-blocks bodysemi-trans— stacked attributes above anfnattr— single attribute with args
Misc
debug: Enable debug logging for development and troubleshooting.external-ctor: Use the externalctorcrate instead of Hotaru's built-in constructor implementation. When enabling, you must also addctorto your dependencies:[dependencies] hotaru = { version = "0.8.3", features = ["external-ctor"] } ctor = "0.4.0" tokio = { version = "1", features = ["full"] }
Example — HTTPS server with body compression:
[dependencies]
hotaru = { version = "0.8.3", features = ["https", "http_compression"] }
tokio = { version = "1", features = ["full"] }Example — gRPC-only (no HTTP):
[dependencies]
hotaru = { version = "0.8.3", default-features = false, features = ["trans", "tokio"] }
hotaru_grpc = "..."
tokio = { version = "1", features = ["full"] }Use the CLI to scaffold projects — it generates build.rs for asset copying and src/resource.rs for runtime template/static lookup, which are non-trivial to wire up by hand.
cargo install hotaru # install the CLI (see Installation above)
hotaru new my_app # scaffold a new project
hotaru init # or scaffold into the current Cargo crate
cd my_app && cargo run # serves http://127.0.0.1:3003my_app/
├── Cargo.toml # Dependencies and project metadata
├── build.rs # Asset copying build script
├── src/
│ ├── main.rs # Application entry point with LServer! + endpoint!
│ └── resource.rs # Resource locator helpers
├── templates/ # Akari HTML templates
└── programfiles/ # Static assets (CSS, JS, images)
The build script copies templates/ and programfiles/ to the target directory at compile time so they're accessible at runtime.
Three macro flavors, enabled by the trans / semi-trans / attr cargo features. Pick one per project; trans is the default. All three register the same route at startup; they only differ in syntax.
trans (default) — bang macro with hotaru-blocks body:
endpoint! {
APP.url("/users/<int:id>"),
pub get_user<HTTP> {
let user_id = req.param("id").unwrap_or_default();
akari_json!({ id: user_id })
}
}semi-trans — stacked attributes above an fn:
#[endpoint]
#[url("/users/<int:id>")]
pub fn get_user<HTTP>() {
let user_id = req.param("id").unwrap_or_default();
akari_json!({ id: user_id })
}attr — single attribute with args:
#[endpoint("/users/<int:id>")]
pub fn get_user<HTTP>() {
let user_id = req.param("id").unwrap_or_default();
akari_json!({ id: user_id })
}
akari_json!is the JSON-response macro re-exported viahotaru::prelude; it already wrapsjson_response(...)so callers don't compose the two. Keys are bare idents (not"...").req.param(...)returnsOption<String>.
- Endpoints and middleware auto-register at startup — no manual
router.register(). transform: brace syntax{}with doc comments inside the block; angle-bracket body defaults toreq. Optional fn-stylepub fn name(req: HTTP) { ... }is also accepted.- Remaining readme examples use
trans. To switch, setdefault-features = falseon thehotarudependency and turn on the flavor you want, e.g.hotaru = { version = "0.8.3", default-features = false, features = ["semi-trans", "http", "tokio"] }. Cargo feature unification would otherwise keeptranson alongside it; remember to re-addhttpandtokiosincedefault-features = falsealso drops the default HTTP stack and Tokio facade defaults. - See
macro_ra.mdfor syntax details. Analyzer support is planned.
Attach a middleware to a protocol via the ProtocolBuilder. Add htmstd = "0.8" to your Cargo.toml for the bundled middleware library:
use htmstd::CookieSession;
LServer!(
APP = Server::new()
.binding("127.0.0.1:3003")
.single_protocol(
ProtocolBuilder::new(HTTP::server(HttpSafety::default()))
.append_middleware::<CookieSession>(),
)
.build()
);CookieSession writes encrypted session cookies. By default, those cookies are
production-safe (Secure, HttpOnly, SameSite=Lax, Path=/). If you are
running a plain-HTTP development environment, configure the cookie safety policy
explicitly through the app config:
use htmstd::{CookieSecurity, CookieSession, CookieSessionSettings};
LServer!(
APP = Server::new()
.binding("127.0.0.1:3003")
.mode(RunMode::Development)
.set_config(CookieSessionSettings::new().security(CookieSecurity::Auto))
.single_protocol(
ProtocolBuilder::new(HTTP::server(HttpSafety::default()))
.append_middleware::<CookieSession>(),
)
.build()
);CookieSecurity::Auto follows RunMode: Production/Beta keep Secure
cookies, while Development/Build allow plain HTTP cookies. For production,
also configure a stable SessionSecret so sessions survive process restarts.
Middleware can also be attached per-endpoint via middleware = [...] inside the endpoint! block — see example_hotaru for the pattern.
Render HTML with Akari via akari_render! — the macro looks up the template file and substitutes the named bindings:
endpoint! {
APP.url("/profile"),
pub profile<HTTP> {
akari_render!("profile.html", name = "Alice")
}
}Configure request validation per endpoint:
endpoint! {
APP.url("/upload"),
config = [HttpSafety::new()
.with_max_body_size(50 * 1024 * 1024) // 50MB
.with_allowed_methods(vec![HttpMethod::POST])
],
pub upload<HTTP> {
// Handle file upload
}
}Check out the example repository for:
- Basic routing and handlers
- Form processing and file uploads
- Session management with cookies
- CORS configuration
- Multi-protocol applications
Hotaru is built on a modular architecture:
- hotaru - Main framework with convenient API
- hotaru_core - Core protocol and routing engine
- hotaru_trans - Procedural macros for endpoint! and middleware!
- hotaru_http - HTTP implementation for Hotaru
- hotaru_tls - TLS/HTTPS implementation for Hotaru
- hotaru_rt_tokio - Tokio runtime backend (
TokioRuntime) - hotaru_io_tokio - Tokio TCP/IO backend (
TcpTransport,TokioIo) - hotaru_io_futures -
futures-ioadapter backend (FuturesIo, experimental) - hotaru_io_embedded -
embedded-io-asyncadapter backend (EmbeddedIo) — experimental; in-workspace, unpublished (crates.io), and re-exported byhotaruwhenio_embeddedis enabled - hotaru_lib - Utility functions (compression, encoding, etc.)
- htmstd - Standard middleware library (CORS, sessions)
- Continued backend split work by moving Tokio-specific IO/runtime support out of
hotaru_core. - Clarified platform and task-mobility feature modes.
- Added explicit local-executor refinements:
spawn_local_atomicandspawn_local_no_atomic. - Made sync primitive selection feature-based:
parking_lot,spin, or HotaruRefCellfallback. - Removed hidden
target_has_atomicbehavior from core feature selection. - Replaced the old
full/literegex names with additivefull_regex/lite_regex; when neither is enabled, Hotaru drops theregexdependency and uses its regex-stub path. - Split facade regex style from template support:
full_regex/lite_regexcontrol routing regex, whiletemplatecontrols Akari template support. - Added
hotarufacade re-exports forEmbeddedIobehindio_embedded, and exposed the experimental Embassy backend crate behindembassy. - Added CI coverage for the
hotarufacade on a no-atomic bare-metal target, and deduplicated the core feature matrix so each feature combination is compiled once. - Updated repository metadata and documentation links for the transfer to
https://github.com/Field-of-Dream-Studio/hotaru. - Continued preparation for a smaller backend-neutral core.
- Core/backend split:
hotaru_coreis now backend-neutral at the public type layer. Concrete Tokio runtime and TCP/IO implementations moved into sibling crates (hotaru_rt_tokio,hotaru_io_tokio), while the umbrellahotarucrate keeps the familiar Tokio defaults. - IO adapter crates: futures-io and embedded-io-async adapters moved out of core into
hotaru_io_futuresandhotaru_io_embedded. Each backend uses local wrapper types (TokioIo<T>,FuturesIo<T>,EmbeddedIo<T>) so adapter impls stay additive and avoid trait-coherence conflicts. - Simpler
hotaru_corefeatures: core no longer ownsio_*,rt_*,tokio, orembassyfeature flags. It now keeps only the platform axis (std/embedded) and task-mobility axis (spawn_send/spawn_local); runtime and IO backends are selected through backend crates, or through optional facade features onhotaru. hotarufacade defaults to Tokio/std: the umbrella keeps Tokio as the supported default path, while exposing experimental optionalembedded,embassy, andio_embeddedfeatures for in-workspace backend work.io_embeddedre-exportsEmbeddedIo; the backend crate remains unpublished on crates.io.- Runtime abstraction cleanup:
RuntimeSpecis the backend-neutral runtime trait, with Tokio implemented externally byhotaru_rt_tokio::TokioRuntime. Framework types (Server,Client, builders, and URL/protocol-entry types) now carry explicit transport/runtime parameters in core, whilehotarurestores ergonomic defaults. MaybeSendtask-mobility model: async framework surfaces useMaybeSendsospawn_sendbuilds keep realSendbounds andspawn_localbuilds can support local!Sendfutures.hotaru_io_embeddedgates its actual embedded-io-async trait impls onspawn_local, not on theembeddedplatform flag.- Framework-owned async IO traits:
HotaruRead,HotaruWrite,HotaruBufRead,HotaruBufWrite,HotaruIOError,HotaruBufReader, andHotaruBufWriterprovide the common IO trait surface used by transports and protocols without hardcoding Tokio types in core. - Native async trait surfaces: core transport/protocol traits use return-position
impl Futureinstead ofasync-trait, reducing proc-macro dependency surface and avoiding unnecessary boxed futures at trait boundaries. - Protocol-agnostic endpoint outcomes:
EndpointOutcome<C>lets generated endpoints apply return values to any request context. HTTP keeps the existingHttpResponseendpoint style, while non-HTTP/inbound-only protocols can use()outcomes without placeholder responses. - Per-protocol URL parsing hooks:
Protocolcan customize URL tokenization/literal parsing, and URL parser internals such asRawToken,TypeKind,tokenize, andtokens_to_patternsare re-exported for protocol-specific routing work. - Preferred-language middleware:
htmstdaddsPreferredLanguageMiddleware,PreferredLanguage, settings, and request-extension helpers for parsing and negotiating theAccept-Languageheader. - no_std preparation: core continues moving toward
no_stdreadiness withallocusage,coreimports, Akariembedded/no_stdalignment, generic IO errors, and backend-neutral abstractions. Embassy and embedded backend work exists in-tree but remains experimental. - Sync-main entry macros:
run_server!/run_server_until!(blocking) andrun_server_no_block!/run_server_no_block_until!(fire-and-forget) let users run a server from an ordinaryfn main()— no#[tokio::main], noasync fn main. Backed by a newBlockingRuntimeCapcapability trait implemented byTokioRuntime.
httpandhttp_compressionmoved to optional features (compression default-off)- HTTP re-exports relocated to
hotaru::http - Clean builds ~35% faster (dropped
tracing, gated heavy codecs) regexbumped 1.5.6 -> 1.12AccessPointTableswitched toPRwLock(no more poisoning)hotaru_trans..middleware inheritance now honors the URL's app identhotaru_transanonymous-fn_form fixed- Client / outpoint runtime paired with
Client<TS>, theoutpoint!macro, andrun!/call!invocation sugar - Protocol trait reshape: channel-based
open_channel/handle/send; newChanneltrait +ProtocolFlow RequestContextrework:Defaultsupertrait,type Channelanchor,inject_request/into_response; newEmptyError- Result-typed execution chain — no boxing at chain boundaries
- Named access points with a single canonical registration funnel
- Instance-based transports:
TransportSpec::Inbound/OutboundreplaceAccepter/Connector - HTTPS feature:
HTTPS = Http1Protocol<TlsStream, TlsTransport> - New
LServer!/LClient!/LUrl!/LPattern!macros replaceLApp!
- Multi-protocol support (HTTP, WebSocket, custom TCP)
- Enhanced security controls with HttpSafety
- Improved middleware system with protocol inheritance
- Performance optimizations in URL routing
- Comprehensive security testing
.worker()method now properly configures dedicated worker threads per Server instance- Fixed
hotaru newandhotaru initto generate correctendpoint!macro syntax - Built-in constructor implementation (no external
ctordependency required) - Fn-style blocks: New syntax
pub fn name(req: HTTP) { ... }forendpoint!andmiddleware!macros (original hotaru blocks syntax preserved) - Bug fix for URL routing
- Protocol abstraction layer
- Request context improvements
- Standard middleware library (htmstd)
- Cookie-based session management
- Async/await support with Tokio
- Akari templating integration
- Cookie manipulation APIs
- File upload handling
- Form data processing improvements
- Akari Template Engine: https://crates.io/crates/akari
- Homepage: https://hotaru.rs
- Documentation Home Page: https://fds.rs
- GitHub: https://github.com/Field-of-Dream-Studio/hotaru
- Documentation: https://docs.rs/hotaru
| Video Resources | URL |
|---|---|
| Quick Tutorial | Youtube: https://www.youtube.com/watch?v=8pV-o04GuKk&t=6s Bilibili: https://www.bilibili.com/video/BV1BamFB7E8n/ |
Definitions and component declarations are maintained in GOVERNANCE.md.
MIT License — see LICENSE.txt.
Copyright (c) 2024-2026 @ Field of Dreams Studio (FDS) & Project-StarFall & PMINE-FDS