http-rs/tide
Fast and friendly HTTP server framework for async Rust
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓24+ active contributors
- ✓Distributed ownership (top contributor 23% of recent commits)
- ✓Apache-2.0 licensed
Show all 6 evidence items →Show less
- ✓CI configured
- ✓Tests present
- ⚠Stale — last commit 2y ago
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/http-rs/tide)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/http-rs/tide on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: http-rs/tide
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/http-rs/tide shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- 24+ active contributors
- Distributed ownership (top contributor 23% of recent commits)
- Apache-2.0 licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 2y ago
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live http-rs/tide
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/http-rs/tide.
What it runs against: a local clone of http-rs/tide — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in http-rs/tide | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 884 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of http-rs/tide. If you don't
# have one yet, run these first:
#
# git clone https://github.com/http-rs/tide.git
# cd tide
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of http-rs/tide and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "http-rs/tide(\\.git)?\\b" \\
&& ok "origin remote is http-rs/tide" \\
|| miss "origin remote is not http-rs/tide (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "src/lib.rs" \\
&& ok "src/lib.rs" \\
|| miss "missing critical file: src/lib.rs"
test -f "src/server.rs" \\
&& ok "src/server.rs" \\
|| miss "missing critical file: src/server.rs"
test -f "src/router.rs" \\
&& ok "src/router.rs" \\
|| miss "missing critical file: src/router.rs"
test -f "src/middleware.rs" \\
&& ok "src/middleware.rs" \\
|| miss "missing critical file: src/middleware.rs"
test -f "src/endpoint.rs" \\
&& ok "src/endpoint.rs" \\
|| miss "missing critical file: src/endpoint.rs"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 884 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~854d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/http-rs/tide"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Tide is an async-first HTTP server framework for Rust that prioritizes developer ergonomics and rapid prototyping. It handles HTTP/1.1 protocol management via async-h1, provides composable middleware, built-in routing via routefinder, and first-class support for JSON serialization, cookies, sessions, and static file serving—all with minimal boilerplate required to build production-grade web services. Modular design with three layers: src/lib.rs orchestrates the main App/Server, src/middleware.rs + src/endpoint.rs define the request/response pipeline, and src/listener/ abstracts over transport (TCP, Unix sockets, concurrent listeners). Features are split into optional modules: src/cookies/, src/fs/ (serve_dir, serve_file), src/log/ middleware, and src/redirect. Benches/ has routing/nesting performance tests; examples/ demonstrates every major feature in isolation.
👥Who it's for
Rust developers building REST APIs, web applications, and microservices who want to leverage async/await without the complexity of lower-level frameworks like Hyper. Specifically targets teams migrating from Express.js or other pragmatic frameworks and seeking Rust's performance guarantees while maintaining rapid iteration.
🌱Maturity & risk
Actively developed and production-ready at version 0.17.0-beta.1. The project has robust CI via GitHub Actions (ci.yaml), comprehensive examples in examples/, test fixtures including feature-gated tests (cookies.rs, nested), and a full dual-license setup (MIT/Apache-2.0). Recent feature additions (sessions, SSE support via async-sse) and active maintenance indicate ongoing investment.
Low-to-moderate risk: the codebase is relatively lean (~229KB Rust code) with well-scoped dependencies (async-std, http-types, routefinder), reducing supply-chain exposure. However, it remains in beta (0.17.0-beta.1), and the small core team means breaking changes could occur; adoption should wait for 0.18+ stable release if targeting critical production systems. No evidence of stale maintenance—active CI and example updates suggest healthy activity.
Active areas of work
The project is stabilizing toward 0.18 release: beta versioning, feature flags for optional functionality (sse, sessions, logger), and active example additions (graphql.rs, sse.rs). The listener abstraction (concurrent_listener.rs, failover_listener.rs, unix_listener.rs) is being hardened for production use. No specific open issues visible in the file list, but the CONTRIBUTING.md and SECURITY.md presence indicate active governance.
🚀Get running
git clone https://github.com/http-rs/tide.git
cd tide
cargo build
cargo run --example hello
# Server listens on 127.0.0.1:8080 by default
To run tests: cargo test --all-features. To run benchmarks: cargo bench.
Daily commands:
cargo run --example hello
# Output: listening on http://127.0.0.1:8080
# Test with: curl http://127.0.0.1:8080
For JSON example: cargo run --example json, then curl -X POST http://127.0.0.1:8080 -H 'Content-Type: application/json' -d '{"name":"test"}'.
🗺️Map of the codebase
src/lib.rs— Entry point and public API surface—defines Server, App, and core re-exports that all contributors must understand.src/server.rs— Core Server struct and lifecycle management—essential for understanding request handling and listener configuration.src/router.rs— Router implementation with route matching logic—critical for understanding how endpoints are registered and dispatched.src/middleware.rs— Middleware trait and composition model—foundational for understanding the request/response pipeline.src/endpoint.rs— Endpoint trait and handler abstraction—defines how business logic integrates with the framework.src/request.rs— Request wrapper around http-types—primary interface for accessing incoming HTTP data and route parameters.src/response.rs— Response and ResponseBuilder types—essential for understanding how to construct HTTP responses.
🛠️How to make changes
Add a new HTTP endpoint
- Define an endpoint handler function or struct implementing the Endpoint trait in your application code (
src/endpoint.rs) - Register the route on the App or Route using
.at('/path').post(handler)or.at('/path').get(handler)methods (src/router.rs) - Access request data via the Request parameter—use
.param('name')for path params,.body().text().awaitfor body (src/request.rs) - Return a type that implements Into<Response>—typically String, JSON, or a Response object from response_builder (
src/response.rs) - See examples/hello.rs or examples/json.rs for concrete patterns (
examples/hello.rs)
Add request/response middleware
- Implement the Middleware trait with an async fn handle(&mut self, req: Request, next: Next) method (
src/middleware.rs) - Call next.run(req).await to invoke downstream middleware/endpoint; inspect or modify request/response before and after (
src/middleware.rs) - Register globally on App with
.with(your_middleware)or per-route with.with(your_middleware)on a Route (src/route.rs) - Study examples/middleware.rs and src/log/middleware.rs for patterns (
examples/middleware.rs)
Add a custom listener transport
- Implement the Listener trait from src/listener/mod.rs with async accept() returning a TlsStream or similar (
src/listener/mod.rs) - Implement ToListener to allow App::listen(your_listener) syntax (
src/listener/to_listener.rs) - Add a new variant to the parsed_listener if supporting connection string syntax (e.g., 'tls://...') (
src/listener/parsed_listener.rs) - See src/listener/tcp_listener.rs and src/listener/unix_listener.rs as reference implementations (
src/listener/tcp_listener.rs)
Add a state management or dependency injection feature
- Store state in App via .with_state(shared_state) or use Server::with_state() before listen (
src/server.rs) - Access state in endpoints via req.state::<T>() to retrieve a cloneable Arc<T> (
src/request.rs) - See examples/state.rs for a concrete pattern (
examples/state.rs)
🔧Why these technologies
- async/await + async-h1 — Non-blocking I/O enables handling thousands of concurrent requests on a single thread; h1 provides fast, simple HTTP/1.1 parsing without full TLS complexity
- http-types crate — Standardized HTTP request/response abstractions (not hyper) reduce boilerplate and allow pluggable listeners for multiple transports
- Arc<State> + Clone — Immutable shared state with clone-on-access avoids locking overhead for common stateless handlers; interior mutability available via Mutex/RwLock when needed
- Pluggable Listeners (Listener trait) — Enables TCP, Unix sockets, TLS, and custom transports without coupling core router to network details
- Middleware + Next pattern — Composable async pipeline allows orthogonal concerns (logging, auth, compression) without tangling in handler logic
⚖️Trade-offs already made
-
No built-in ORM or database integration
- Why: Minimalism—allow users to bring their own async database driver (sqlx, sea-orm, etc.)
- Consequence: Lower barrier to entry but developers must manage database pooling and integration themselves
-
In-memory session storage by default
- Why: Simplicity for demos and small apps; avoids hidden Redis/persistence dependencies
- Consequence: Sessions lost on server restart; production deployments need custom session middleware
-
No request/response body streaming in the core API (uses buffered body)
- Why: Simpler error handling and middleware composition; most web apps don't need true streaming
- Consequence: Large file uploads/downloads benefit less from zero-copy efficiency; multipart/chunked still works but buffered
-
Type-driven routing (Endpoint trait) rather than macro-heavy
- Why: Explicit and introspectable; easier to understand control flow without derive magic
- Consequence: More boilerplate for complex handlers vs. frameworks with heavy code generation (e.g., Actix-web)
🚫Non-goals (don't propose these)
- Does not provide built-in authentication or authorization—that is a middleware responsibility
- Does not include database drivers or ORMs—use async-compatible crates (sqlx, sea-orm, etc.) directly
- Not a WebSocket-first framework—SSE and upgrade are supported but WebSocket requires external crates
- Does not force a specific templating engine—use handlebars, tera, askama as dependencies
- Not a full-stack framework—no frontend asset building, ORM, or admin panel
🪤Traps & gotchas
Async runtime binding: Tide is built on async-std, not Tokio; projects mixing both runtimes will deadlock. Feature flag coupling: cookies feature requires http-types/cookies; sessions requires both cookies AND async-session—forgetting this causes compile failures. Listener trait object: to_listener trait returns Box<dyn Listener>; custom listeners must implement Send + Sync + 'static. State<T> type parameter: App<State<()>> is the default, but State<T> is invariant in T—wrong state type won't deserialize silently. No built-in request size limits: file uploads via examples/upload.rs need explicit length checks to avoid memory exhaustion.
🏗️Architecture
💡Concepts to learn
- Async/await futures — Tide is built entirely on async Rust; every handler is an async fn returning an impl Future—understanding Future trait, poll(), and Pin is mandatory for anything beyond trivial examples
- Middleware composition via Next trait — Tide's power comes from stacking middleware (logging, auth, CORS, compression) via a functional pipeline; the Next trait and impl IntoMiddleware pattern are non-obvious but central to extending behavior
- HTTP/1.1 multiplexing and keep-alive — Tide delegates to async-h1 for protocol handling; understanding keep-alive connection pooling and chunked transfer encoding is necessary for debugging performance and streaming responses (see examples/chunked.rs, examples/sse.rs)
- Type-driven routing and extraction — Tide uses Rust's type system to extract route parameters and deserialize bodies (req.body_json(), req.param(), State<T>); Serde integration is implicit and powerful, but type mismatches produce cryptic errors
- Server-Sent Events (SSE) and streaming responses — examples/sse.rs and async-sse dependency enable pub/sub and real-time updates; understanding how Tide buffers vs. flushes responses to clients is critical for latency-sensitive applications
- Trait objects and dyn Listener — src/listener/to_listener.rs uses trait objects (Box<dyn Listener>) to abstract over TCP, Unix sockets, and custom transports; understanding monomorphization vs. dynamic dispatch helps avoid runtime panics and performance regressions
- Cookie and session state management — src/cookies/middleware.rs and sessions feature (async-session) show how to store signed/encrypted state on the client; misunderstanding HMAC or SameSite attributes leads to CSRF and XSS vulnerabilities
🔗Related repos
actix/actix-web— Direct competitor: higher performance but steeper learning curve; Tide users often evaluate against Actix for large deploymentstokio-rs/axum— Newer alternative by Tokio team: more composable middleware via tower, uses Tokio instead of async-std; represents the ecosystem shift post-2021http-rs/http-types— Tide's HTTP semantic layer: shared dependency that decouples HTTP types from runtime; Tide contributors also maintain thisasync-rs/async-std— Runtime dependency and sister project: Tide is the reference async-std web framework; critical for understanding executor behaviorroutefinder/routefinder— Routing engine: trie-based router that Tide uses; understanding its parameters (e.g., segment matching) helps optimize route definitions
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive tests for src/listener module with all transport types
The listener module (src/listener/) has multiple implementations (tcp_listener.rs, unix_listener.rs, concurrent_listener.rs, failover_listener.rs) but there are no dedicated test files in tests/ directory for listener functionality. This is critical infrastructure that handles server bindings. Adding tests would ensure robustness across TCP, Unix sockets, concurrent listeners, and failover scenarios.
- [ ] Create tests/listener_tcp.rs to test TCP listener binding, connection handling, and error cases
- [ ] Create tests/listener_unix.rs to test Unix socket listener on supported platforms
- [ ] Create tests/listener_concurrent.rs to test concurrent listener with multiple bindings
- [ ] Create tests/listener_failover.rs to test failover behavior between listeners
- [ ] Verify all listener implementations in src/listener/*.rs are covered by integration tests
Add missing test file for src/sessions/middleware.rs with feature flag
The Cargo.toml shows a sessions feature that depends on cookies and async-session, and there's a src/sessions/middleware.rs file, but the tests/ directory lacks a corresponding sessions test file. The Cargo.toml snippet is truncated (ends with '[[test]] name = "nested" path = "tes'), suggesting a sessions test configuration may be missing. This is important for validating session middleware behavior.
- [ ] Create tests/sessions.rs with required-features = ["sessions"]
- [ ] Add test cases for session creation, storage, retrieval, and expiration
- [ ] Test session middleware integration with the router and request/response cycle
- [ ] Add [[test]] configuration entry in Cargo.toml for sessions test with proper feature gates
- [ ] Test edge cases like concurrent session access and session data serialization
Add integration tests for src/fs/serve_dir.rs and serve_file.rs with various edge cases
The fs module (src/fs/) provides file serving functionality but lacks dedicated test coverage in the tests/ directory. Given that serve_dir.rs and serve_file.rs handle file I/O and can have security/performance implications, comprehensive tests are critical. Currently only chunked-encode tests exist.
- [ ] Create tests/fs_serve_file.rs to test serving individual files, various mime-types, and large files
- [ ] Create tests/fs_serve_dir.rs to test directory traversal protection, directory listing, and nested paths
- [ ] Add tests for error cases: missing files, permission denied, directory as file, symlink handling
- [ ] Test Range header support and partial content delivery
- [ ] Test interaction with src/fs/mod.rs implementation and verify proper error propagation
🌿Good first issues
- Add timeout middleware example: src/middleware.rs exists but examples/timeout.rs is missing; contributing a middleware that enforces request deadlines using async-std::task::timeout teaches the middleware pattern and fills a common need
- Document State<T> extraction patterns in examples: examples/state.rs exists but lacks inline comments on how State<AppState> flows through handlers; adding doc comments and a second variant (e.g., State<Arc<Db>>) would clarify the most confusing API surface
- Add integration tests for listener failover behavior: src/listener/failover_listener.rs exists but tests/failover.rs is not in the file list; writing tests that exercise the fallback logic when primary listener fails would improve reliability confidence
⭐Top contributors
Click to expand
Top contributors
- @joshtriplett — 23 commits
- @jbr — 17 commits
- @Fishrock123 — 14 commits
- @yoshuawuyts — 12 commits
- @halvko — 5 commits
📝Recent commits
Click to expand
Recent commits
b32f680— Merge pull request #915 from DaraghD/clippy (Fishrock123)f6e3e03— fix: clippy warnings and cargo fmt (DaraghD)a752efc— Merge pull request #914 from DaraghD/patch-1 (Fishrock123)6708dff— fix: clippy warnings (DaraghD)56fdb6e— docs : grammar (DaraghD)7637a73— Merge pull request #913 from benharvie/main (jbr)e25fb68— Update SECURITY.md (jbr)946b0fa— Create SECURITY.md (benharvie)3d50409— Merge pull request #904 from mmikulski/831-expose-http_types-method (joshtriplett)b5b741f— Remove unneeded braces (joshtriplett)
🔒Security observations
The Tide web framework demonstrates a reasonable security posture with proper use of async Rust and established security patterns (CORS, cookies, sessions). However, there are areas for improvement: (1) Several dependencies are not at their latest versions and should be updated to receive security patches, (2) Some security best practices like HSTS, CSP, and stricter session cookie attributes could be more explicitly supported or documented, and (3) The project is in beta status. No hardcoded secrets, SQL injection risks, or obvious misconfigurations were detected. The security module provides CORS support but could be expanded. Overall, this is a solid foundation that should prioritize dependency updates and enhanced security middleware options.
- Medium · Outdated async-h1 Dependency —
Cargo.toml - async-h1 = { version = "2.3.0", optional = true }. async-h1 version 2.3.0 is used, which may have known vulnerabilities. The dependency should be updated to the latest stable version to ensure security patches are applied. Fix: Update async-h1 to the latest version. Run 'cargo update async-h1' and verify compatibility with the current codebase. - Medium · Outdated http-types Dependency —
Cargo.toml - http-types = { version = "2.11.0", ... }. http-types version 2.11.0 is used. This version may have security vulnerabilities or missing security features. Consider updating to a newer version. Fix: Update http-types to the latest version and test thoroughly. Check the changelog for security-related fixes. - Low · Regex DoS Potential —
Cargo.toml - regex = "1.5.5", src/router.rs, src/route.rs. The codebase includes regex = "1.5.5" dependency and uses routefinder for routing. Complex regex patterns in routing could potentially be vulnerable to ReDoS (Regular Expression Denial of Service) attacks if user input is not properly validated. Fix: Validate and limit route pattern complexity. Use regex::bytes for binary data. Consider adding request timeout middleware to mitigate ReDoS impact. - Low · Missing HSTS Header Configuration —
src/security/cors.rs, src/response_builder.rs. No explicit HSTS (HTTP Strict-Transport-Security) header implementation is visible in the security module. This is important for preventing man-in-the-middle attacks. Fix: Add middleware or response builder support for HSTS headers. Include max-age, includeSubDomains, and preload directives. - Low · Session Security Configuration Not Visible —
src/sessions/middleware.rs, src/cookies/middleware.rs. Sessions implementation exists but session cookie security attributes (HttpOnly, Secure, SameSite) are not clearly enforced in the visible code structure. Fix: Ensure session cookies have HttpOnly and Secure flags set by default. Implement SameSite=Strict or SameSite=Lax for CSRF protection. - Low · Missing Content-Security-Policy Support —
src/security/. No explicit Content-Security-Policy (CSP) middleware or builder support is evident in the security module. Fix: Implement CSP middleware to allow applications to define acceptable content sources and prevent XSS attacks. - Low · Beta Version in Use —
Cargo.toml - version = "0.17.0-beta.1". The package version is 0.17.0-beta.1, indicating this is a beta/pre-release version that may not have undergone full security review. Fix: Ensure security review is completed before finalizing release. Consider using stable release versions in production environments.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.