The Hotaru 0.8 era starts from 23/May/2026.
Hotaru Web Framework
Small, sweet, easy framework for full-stack Rust web applications
Overview
Hotaru is a lightweight, intuitive web framework focused on simplicity and productivity. It supports regex-based routing, tree-structured URLs, and integrates seamlessly with the Akari templating system.
MSRV: 1.86
Key Features
- Multi-Protocol Support: Handle HTTP/HTTPS, WebSocket, and custom TCP protocols
- Simple API: Intuitive request/response handling with minimal boilerplate
- Full-Stack: Built-in template rendering with Akari templates
- Flexible Routing: Support for regex patterns, literal URLs, and nested routes
- Asynchronous: Built with Tokio for efficient async handling
- Form Handling: Easy processing of form data and file uploads
- Middleware Support: Create reusable request processing chains
Quick Start
use *;
use *;
LServer!;
async
endpoint!
Installation
Using the CLI Tool (Recommended)
Install the Hotaru CLI tool:
Create a new project:
Manual Installation
Add to your Cargo.toml:
[]
= "0.8.1"
= { = "1", = ["full"] }
Optional Features
Hotaru supports the following optional features:
-
debug: Enable debug logging for development and troubleshooting -
https: HTTPS support — pulls inhotaru_tlsand surfacesHTTPS/TlsTransport/TlsOutboundTarget/TlsClientConfig -
external-ctor: Use the externalctorcrate instead of Hotaru's built-in constructor implementationNote: When enabling
external-ctor, you must also addctorto your dependencies:[] = { = "0.8.1", = ["external-ctor"] } = "0.4.0" # Required when external-ctor feature is enabled = { = "1", = ["full"] }By default, Hotaru uses a built-in constructor implementation that doesn't require any external dependencies.
Binary Commands
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.
&&
Project Structure
my_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.
Core Concepts
Endpoints
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!
semi-trans — stacked attributes above an fn:
attr — single attribute with args:
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>.
Macro Notes
- 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.1", default-features = false, features = ["semi-trans"] }. Cargo feature unification would otherwise keeptranson alongside it. - See
macro_ra.mdfor syntax details. Analyzer support is planned.
Middleware
Attach a middleware to a protocol via the ProtocolBuilder. Add htmstd = "0.8" to your Cargo.toml for the bundled middleware library:
use CookieSession;
LServer!;
Middleware can also be attached per-endpoint via middleware = [...] inside the endpoint! block — see example_hotaru for the pattern.
Templates
Render HTML with Akari via akari_render! — the macro looks up the template file and substitutes the named bindings:
endpoint!
HTTP Safety Configuration
Configure request validation per endpoint:
endpoint!
Examples
Check out the example repository for:
- Basic routing and handlers
- Form processing and file uploads
- Session management with cookies
- CORS configuration
- Multi-protocol applications
Crate Ecosystem
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_lib - Utility functions (compression, encoding, etc.)
- htmstd - Standard middleware library (CORS, sessions)
Changelog
0.8.1 (Current)
WalkCursor+UrlRoot::walk_cursor(unstable): resumable URL-tree traversal cursor. Drains every node whose path-pattern matches a given path, in priority order (literal → regex →*→**). Foundation for fan-out protocols (MQTT publish → matching subscriptions, broadcast hooks); existingwalk/walk_strare unchanged.EmptyError: zero-payload template error type implementing every boundRequestContext::Errorrequires (ProtocolError,From<std::io::Error>,Send + Sync + 'static). Use it when prototyping a newRequestContextimpl, in tests, or in protocols with no meaningful error payload.RequestContext::Error: From<std::io::Error>: this bound is now part of the trait itself rather than everyClient::*method's where-clause. The client path touches transport-level I/O which surfacesstd::io::Error, so every protocol's error type has to absorb it. Breaking for hand-writtenRequestContextimpls whoseErrortype doesn't already convert fromio::Error— add aFrom<std::io::Error>impl or useEmptyError.Protocol::acquire_channel: client-side mirror ofopen_channel. Default flow dials fresh per request; multiplexing protocols (HTTP/2, MQTT) can slot a connection pool behind this method without changing the signature. Internally backed by the instance-cachedArc<TS::Outbound>onClient.
0.8.0
- Client / outpoint runtime: new
Client<TS>for outbound traffic, mirroringServer<TS>. IncludesClient::request_fn,Client::call_fn,Client::call_urlfor one-shot and persistent outpoint invocation. outpoint!macro: client-side counterpart toendpoint!. The user body becomes the outermost middleware; thesend;marker triggers the registered chain (terminating in<P as Protocol>::send(ctx).await).run!andcall!macros: invocation-style sugar —run!(APP<HTTP>::name, request)->APP.request_fn::<HTTP>("name", request);call!(APP<HTTP>::name)->APP.call_fn::<HTTP>("name")(plus: "/path"form forcall!).- Protocol trait reshape: channel-based
open_channel/handle(channel, runtime, root)/send(ctx) -> ctx, plus a per-protocolinstall_channel(&mut ctx, channel)bridge.type Context: RequestContext<Channel = Self::Channel>pins channel-type alignment. - RequestContext trait:
Defaultsupertrait; declarestype Channel: Channelas a type anchor only (channel lives as a private field on each concrete context — no trait-exposed accessor). Addsinject_request/into_response.type Error: ProtocolErroris the single source of truth for chain errors. - Result-typed execution chain: middleware, final handlers,
ExecutionChain::run, andUrlNode::runall returnResult<C, <C as RequestContext>::Error>— no boxing at the chain boundary. - Named access points: every registered endpoint/outpoint has an explicit name.
ProtocolEntry::register(name, path, step_names, binding, config)is the single canonical funnel;AccessPointTableper protocol entry refreshes Node-variant entries on rebind.Server::url(url, name, ...)/Client::url(url, name, ...)are URL-first. - Instance-based transports:
TransportSpec::Inbound/Outboundreplace the oldAccepter/Connectorshape.TcpInbound::bind(target)andTcpOutbound::build(target)materialize once perServer/Client. - HTTPS feature: new
httpscargo feature on the umbrellahotarucrate forwards tohotaru_http/tls, surfacingHTTPS,TlsTransport,TlsOutboundTarget,TlsClientConfig.HTTPS = Http1Protocol<TlsStream, TlsTransport>. Channeltrait +ProtocolFlow: per-exchange close semantics (HTTP/1 closes the connection; multiplexed protocols may close only the stream).Channel: Cloneis the framework's sharing contract; protocols are free to back the handle withArc<...>internally.- New
LServer!,LClient!,LUrl!,LPattern!macros for simplified lazy static declarations (replaces the oldLApp!). Defaults toTcpTransport; HTTPS clients withClient<TlsTransport>currently need a directLazy::new(...)declaration until theLClient!type-parameter passthrough lands.
0.7.x
- 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
0.6.x
- Protocol abstraction layer
- Request context improvements
- Standard middleware library (htmstd)
- Cookie-based session management
0.4.x and earlier
- Async/await support with Tokio
- Akari templating integration
- Cookie manipulation APIs
- File upload handling
- Form data processing improvements
Learn More
- Akari Template Engine: https://crates.io/crates/akari
- Homepage: https://hotaru.rs
- Documentation Home Page: https://fds.rs
- GitHub: https://github.com/Field-of-Dreams-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/ |
AI Declaration of each Mod
We believe in transparency about AI-assisted development. The framework is governed jointly by two maintainer groups using a shared four-tier system that prioritizes understanding over line counts.
Maintained by: PMINE/Research
| Name | Tier | Comments |
|---|---|---|
| hotaru_core/app | Author-Owned | |
| hotaru_core/connection | Author-Owned | |
| hotaru_core/executable | Author-Owned | |
| hotaru_core/url | Author-Owned | |
| hotaru_core/protocol | Author-Owned | |
| hotaru_http/trails | Co-Authored | |
| hotaru_http/* | Human-Led | |
| hotaru_mqtt/broker | Co-Authored | |
| hotaru_mqtt/traits | Co-Authored | |
| hotaru_mqtt/* | Human-Led | |
| hotaru_lib | Human-Led | Basic API Access |
| h2per | Co-Authored | Integration of Hyper - Not stable yet |
| htmstd/cors | Human-Led | |
| htmstd/session | Human-Led |
Maintained by: Project-StarFall
| Name | Tier | Comments |
|---|---|---|
| hotaru_trans/endpoint | Author-Owned | Proof and language design must be fully understood by humans |
| hotaru_trans/outpoint | Author-Owned | Proof and language design must be fully understood by humans |
| hotaru_trans/middleware | Author-Owned | Proof and language design must be fully understood by humans |
| hotaru_trans/cors | Co-Authored | Trivial user-level abstraction |
| ahttpm | Co-Authored | Imports akari_macro plus improvements |
| SFX | Co-Authored | Trivial user-level abstraction |
| akari | External | https://crates.io/crates/akari |
| akari_lang | External (TBD) | |
| akari_macro | External | https://crates.io/crates/akari |
Shared term meanings
| Term | Meaning |
|---|---|
| Forbidden | The intelligence work in this module — design decisions, proof obligations, language semantics, novel logic — is authored by humans. AI is not used for this content (the mechanical/test/doc carve-out in operating rule 2 still applies). Reserved for modules where the work is the thinking, not the typing. |
| Author-Owned | AI may assist with drafts and completion, but the committed code reads as the author's own throughout. A reviewer should not be able to tell where AI helped. The module signals "a human owns the design and the prose." |
| Human-Led | The human authored the structure and the load-bearing pieces; AI filled in helpers, repetitive sections, or boilerplate. Some sections may visibly bear AI's hand, but the design choices and non-trivial logic are clearly human. The author can defend every part without re-consulting AI. |
| Co-Authored | AI participated substantively in both design exploration and implementation. The human author has internalized the result and can defend, modify, and debug without re-prompting. Appropriate for well-understood patterns and third-party integrations. |
The understanding requirement is uniform across Author-Owned, Human-Led, and Co-Authored: the author can explain any line, modify surrounding code without AI help, and walk a reviewer through the code on request. The tiers differ only in where AI's voice is allowed to show through, not in what the author owes the team.
Operating rules
- No quantification. Tiers describe the kind of collaboration, not the amount of AI-authored code. Counting lines is brittle and incentivizes the wrong behavior.
- Tests, documentation, and mechanical typing are permitted in every tier — including Forbidden. AI assistance is allowed across all modules for: unit tests; doc comments and inline prose; and mechanical typing where the design decision has already been made by a human and AI is only writing it out (e.g., applying a settled pattern across similar cases, expanding hand-authored pseudocode, regenerating a table from a spec). The defining criterion is that no intelligence work is delegated to AI — design, proof, and semantics decisions remain with the human. The author remains responsible for understanding what was generated.
- Reviewer-driven understanding check. Any reviewer may flag a PR with "this doesn't feel author-owned" — regardless of the module's tier. The author clears the flag by demonstrating understanding in PR comments or a short walkthrough. Flags are requests for evidence, not accusations.
- Smell-test threshold scales with tier. Author-Owned code is flagged if any section visibly reads as AI-generated. Human-Led is flagged if the structural code reads as AI-generated or AI's hand pervades rather than appearing locally. Co-Authored is flagged only if the author cannot defend the code in review.
- Tier reflects the work, not preferences. Maintainers set tiers based on the nature of the module. If the character of a module changes, the tier is re-set rather than stretched.
- External code is outside this policy. AI-authored code arriving through a third-party crate is governed by that crate's own conventions, transparently linked.
📄 License
MIT License — see LICENSE.txt.
Copyright (c) 2024-2026 @ Field of Dreams Studio (FDS) & Project-StarFall & PMINE-FDS