warp

A composable, filter-based web server framework for Rust built on hyper and Tokio.

Framework
Cargo
v0.4.3
10,365stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
63/100Good
Development Activity44
Maintenance40
Community68
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
72/100Good
Architecture82
Code Quality72
Innovation68
Learning Curve65

Warp is a Rust web server framework built around a single core abstraction: the Filter. Instead of treating routes and middleware as separate concepts, warp lets developers compose small, reusable Filters — for path matching, header extraction, query deserialization, and body parsing — into full request-handling pipelines using combinators like and, or, map, and recover. Built directly on top of hyper, it inherits hyper’s HTTP/1 and HTTP/2 support and its reputation as one of the fastest HTTP implementations available, while exposing async/await ergonomics through Tokio.

Beyond routing, warp ships with out-of-the-box support for JSON and form bodies, multipart uploads, static file and directory serving, WebSockets, access logging, and response compression (gzip, deflate, brotli), each implemented as its own Filter that composes into the rest of an application’s pipeline. A dedicated test module lets developers send mocked requests through a service without spinning up a real socket, and the crate is fully open source under the MIT license with no paid tier or usage restrictions.

What You Get

  • Filter combinators (and, or, map, and_then, recover) for composing path, header, query, and body extraction into request pipelines
  • Built-in JSON, form, and multipart body parsing with automatic (de)serialization via serde
  • Static file and directory serving, plus WebSocket support built on tokio-tungstenite
  • Response compression filters for gzip, deflate, and brotli, gated behind feature flags
  • A warp::test module for sending mocked requests through a service without a live socket

Common Use Cases

  • Building lightweight REST/JSON APIs on top of hyper without a heavyweight framework
  • Serving static assets and single-page app bundles from a Rust backend
  • Adding a WebSocket endpoint to an existing async Rust service
  • Prototyping HTTP services where explicit, typed request validation via Filters is preferred over macro-based routing

Under The Hood

Architecture Warp’s core abstraction is the Filter trait (src/filter/mod.rs), which asynchronously extracts a tuple of values from an in-flight request or rejects it; concrete combinator types — And, Or, Map, AndThen, OrElse, Recover, Unify, UntupleOne — each wrap one or two filters and implement FilterBase themselves, so filter chains are built as nested generic types rather than a dynamic router. Request state flows through a thread-local-like Route context (src/route.rs, via scoped-tls) that individual filters (src/filters/*.rs — path, header, query, body, cookie, fs, ws) read from rather than being passed an explicit request object. src/server.rs wraps a composed filter in a tower_service::Service-compatible adapter and drives it through hyper-util’s server runtime, while BoxedFilter (src/filter/boxed.rs) offers a type-erased escape hatch when static generic composition becomes unwieldy. The result is a layered design — Filter trait, combinator layer, route context, server adapter — where swapping the core Filter trait would ripple through every combinator and every built-in filter module.

Tech Stack Warp targets Rust 2021 edition and builds on hyper 1.x plus hyper-util (server, server-graceful, HTTP/1, HTTP/2, tokio integration) for the actual socket and protocol handling, with tokio itself providing the async runtime (io-util, fs, sync, time). It implements tower_service::Service for interoperability with the broader Tower ecosystem. Body and header handling relies on serde, serde_json, and serde_urlencoded for typed (de)serialization, the headers crate for strongly-typed HTTP header parsing, and multer for multipart form parsing. WebSockets are layered on tokio-tungstenite, compression on async-compression (brotli/gzip/deflate), and content typing on mime/mime_guess. Nearly every optional capability — server, websocket, multipart, compression, test — is gated behind Cargo feature flags, keeping the base dependency footprint small.

Code Quality Integration tests live under tests/ (around 20 files covering CORS, multipart, WebSockets, redirects, static files, headers, and more) and are gated behind the test feature, which pulls in hyper’s client for making real requests through warp::test. CI runs cargo fmt --all --check plus a build matrix across stable, beta, and nightly Rust and across feature combinations (default, multipart, websocket, compression), giving solid cross-configuration coverage. The crate enforces #![deny(missing_docs)], #![deny(missing_debug_implementations)], and #![deny(rust_2018_idioms)] at the crate root, so every public item must be documented and implement Debug — a strict bar most Rust crates don’t set. unwrap() appears in a small number of internal source files, generally for invariants the type system already guarantees rather than fallible external input. There are no dedicated unit tests inside src/ modules; correctness is validated primarily through the top-level integration suite.

API Design Warp’s Filter-as-value model is its defining design choice: routes aren’t declared via a macro DSL or a router struct, they’re built by combining ordinary values with and/or/map/and_then, so the compiler checks the whole request pipeline’s types end to end. This gives good compositional reuse — a Filter built for auth or logging can be .and()-ed onto any other Filter without special framework hooks. The tradeoff shows up in error messages and onboarding: filter chains produce deeply nested generic types, and newcomers coming from macro-routed frameworks (Express-style or Rocket-style attribute routing) have a real learning curve before the combinator style feels natural. The ecosystem has also shifted since warp’s design was introduced — axum, built by the same hyper/tokio circle, now uses an extractor-based API that most new hyper-based Rust services reach for first, so warp’s compositional approach is distinctive but no longer the default choice it once was.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search