poem-web/poem
A full-featured and easy-to-use web framework with the Rust programming language.
Healthy across the board
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.
- ✓Last commit 1w ago
- ✓34+ active contributors
- ✓Distributed ownership (top contributor 29% of recent commits)
Show all 6 evidence items →Show less
- ✓Apache-2.0 licensed
- ✓CI configured
- ✓Tests present
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/poem-web/poem)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/poem-web/poem on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: poem-web/poem
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/poem-web/poem 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 the board
- Last commit 1w ago
- 34+ active contributors
- Distributed ownership (top contributor 29% of recent commits)
- Apache-2.0 licensed
- CI configured
- Tests present
<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 poem-web/poem
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/poem-web/poem.
What it runs against: a local clone of poem-web/poem — 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 poem-web/poem | 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 master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 37 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of poem-web/poem. If you don't
# have one yet, run these first:
#
# git clone https://github.com/poem-web/poem.git
# cd poem
#
# 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 poem-web/poem and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "poem-web/poem(\\.git)?\\b" \\
&& ok "origin remote is poem-web/poem" \\
|| miss "origin remote is not poem-web/poem (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 master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "Cargo.toml" \\
&& ok "Cargo.toml" \\
|| miss "missing critical file: Cargo.toml"
test -f "poem/Cargo.toml" \\
&& ok "poem/Cargo.toml" \\
|| miss "missing critical file: poem/Cargo.toml"
test -f "poem-openapi/Cargo.toml" \\
&& ok "poem-openapi/Cargo.toml" \\
|| miss "missing critical file: poem-openapi/Cargo.toml"
test -f "poem-grpc/Cargo.toml" \\
&& ok "poem-grpc/Cargo.toml" \\
|| miss "missing critical file: poem-grpc/Cargo.toml"
test -f "poem-derive/Cargo.toml" \\
&& ok "poem-derive/Cargo.toml" \\
|| miss "missing critical file: poem-derive/Cargo.toml"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 37 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~7d)"
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/poem-web/poem"
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
Poem is a full-featured, async Rust web framework built on Tokio that provides HTTP/HTTPS routing, middleware, and serialization out of the box. It includes official integrations for OpenAPI/Swagger generation (poem-openapi), gRPC (poem-grpc), AWS Lambda deployment (poem-lambda), and MCP server support (poem-mcpserver), positioning itself as a Rust alternative to Python's FastAPI or Node's Express with async-first design. Monorepo (Cargo workspace with resolver = 2) containing: poem/ (core framework), poem-derive/ + poem-openapi-derive/ (proc macros for routes/schemas), poem-openapi/ (OpenAPI generation), poem-grpc/ + poem-grpc-build/ (gRPC codegen), poem-lambda/ (serverless adapter), poem-mcpserver/ + poem-mcpserver-macros/ (MCP protocol), poem-worker/ (worker runtime). examples/ directory mirrors this: examples/grpc/ has helloworld/ and variants (helloworld_compressed/, jsoncodec/), each with build.rs for protobuf codegen. Disabled examples in examples/disabled/tonic/ show intentional opt-out.
👥Who it's for
Rust backend developers and teams building production web services, REST APIs, or microservices who want type-safe routing with zero-cost abstractions and seamless async/await. Also targets teams needing OpenAPI documentation generation, gRPC services, or serverless Rust deployments to AWS Lambda.
🌱Maturity & risk
Actively developed and production-ready: the workspace publishes 5 stable crates with versions 3.1.12+ (poem core), 5.1.15 (poem-openapi), and 0.5.9 (poem-grpc-build). The project has comprehensive CI/CD in .github/workflows/ (ci.yml, code-coverage.yml, release.yml), enforces unsafe-free code, maintains MSRV of Rust 1.85.0, and includes examples for gRPC, OpenAPI, and Lambda—clear indicators of ongoing maintenance and community confidence.
Low-to-moderate risk: single primary maintainer (sunli) evident from repo metadata, but mitigated by strong test coverage requirements (code-coverage.yml active), dependency management via Dependabot, and clear 'unsafe forbidden' security stance. Workspace spans 8 interconnected crates (poem, poem-openapi, poem-grpc, poem-lambda, etc.), so major version bumps to Tokio 1.39.1 or Serde 1.0.130 could cascade—but pinned workspace dependencies reduce breakage. No evidence of abandoned examples (disabled/tonic folder suggests deliberate exclusion, not rot).
Active areas of work
The repo is in active development: workspace edition is set to 2024 (latest), recent dependency updates visible (Tokio 1.39.1, Serde 1.0.130, Rustls 0.23 + tokio-rustls 0.26 kept in sync), and the presence of poem-mcpserver indicates recent expansion into Claude/LLM tool protocols. CI workflows (ci.yml, code-coverage.yml) run on every commit, and Dependabot is configured (.github/dependabot.yml) suggesting daily vulnerability checks. Release workflow (release.yml) automates publishing.
🚀Get running
git clone https://github.com/poem-web/poem.git
cd poem
cargo build --workspace
cargo test --workspace
cargo run --example helloworld --manifest-path examples/grpc/helloworld/Cargo.toml
Daily commands:
No traditional dev server startup; Poem is a library. Instead, run examples: cargo run --example helloworld --manifest-path examples/grpc/helloworld/Cargo.toml or build and test the workspace: cargo test --workspace. For local development, use cargo build --workspace to verify all member crates compile.
🗺️Map of the codebase
Cargo.toml— Workspace root defining all member crates, dependencies, and versions across poem, poem-openapi, poem-grpc, poem-lambda, and poem-mcpserver—required reading to understand the modular architecture.poem/Cargo.toml— Core framework crate manifest specifying the main web server implementation, routing, middleware, and feature flags that power all HTTP handling.poem-openapi/Cargo.toml— OpenAPI/Swagger integration crate that extends poem with declarative API documentation and validation—critical for understanding schema-driven development patterns.poem-grpc/Cargo.toml— gRPC support crate enabling protobuf-based RPC services alongside HTTP—essential for understanding multi-protocol routing and codec handling.poem-derive/Cargo.toml— Procedural macros crate providing attribute-based route definitions and request/response derives—foundational for the declarative API design philosophy.README.md— Project overview documenting framework philosophy, features, safety guarantees (no unsafe rust), MSRV (1.85), and quick-start patterns..github/workflows/ci.yml— CI/CD pipeline defining build, test, coverage, and release processes—reveals the quality gates and supported platforms.
🛠️How to make changes
Add a new HTTP REST endpoint
- Create a new route handler function in your application crate with #[get], #[post], etc. macro from poem-derive (
poem-derive/Cargo.toml (defines macros) → your_app/src/main.rs (use the macro)) - Define request/response types using #[derive(Serialize, Deserialize)] or OpenAPI schemas with #[derive(Object)] (
your_app/src/main.rs (handler) + poem-openapi/Cargo.toml (schema derives)) - Mount the handler to the App router using .at() or .nest() (
your_app/src/main.rs (App::new().at("/path", handler))) - Optionally wrap with #[derive(OpenApi)] to auto-generate Swagger documentation (
poem-openapi-derive/Cargo.toml (attribute macro) → your_app/src/main.rs (#[OpenApi] struct))
Add a new gRPC service
- Create a .proto file defining your service and messages (
examples/grpc/helloworld/proto/helloworld.proto (reference)) - Add build.rs to compile proto files using prost and poem-grpc-build (
examples/grpc/helloworld/build.rs (pattern) → your_service/build.rs (copy & adapt)) - Implement the generated service trait in your handler code (
examples/grpc/helloworld/src/main.rs (handler implementation reference)) - Mount the gRPC service to your App using .nest() (
your_service/src/main.rs (App::new().nest("/", grpc_service)))
Add OpenAPI documentation to existing endpoints
- Wrap your handler module with #[OpenApi] and decorate endpoints with #[oai(path = "/path", method = "get")] (
poem-openapi-derive/Cargo.toml → your_app/src/api.rs (use OpenApi macro)) - Derive #[derive(Object)] on request/response DTOs with field descriptions (
your_app/src/models.rs (#[derive(Object)] with #[oai(...)])) - Mount the OpenApi struct to serve /openapi.json and /swagger-ui (
your_app/src/main.rs (App::new().nest("/api", api.into())))
Deploy to AWS Lambda or Cloudflare Workers
- Add poem-lambda or poem-worker to Cargo.toml and wrap your App with the runtime adapter (
poem-lambda/Cargo.toml or poem-worker/Cargo.toml → your_app/Cargo.toml (add dependency)) - Modify main.rs to use Lambda or Worker runtime instead of tokio::main (
your_app/src/main.rs (#[lambda] or #[worker::main])) - Update Cargo.toml with target platform and disable default server features (
your_app/Cargo.toml ([profile.release], rustflags, etc.))
🔧Why these technologies
- Rust + async/await (tokio) — Memory-safe, zero-cost abstractions, and high concurrency for web servers without garbage collection overhead
- Procedural macros (poem-derive, poem-openapi-derive) — Declarative, compile-time route and schema generation reduce boilerplate and enable type-safe request routing
- Protocol Buffers + gRPC (poem-grpc) — Multi-language RPC support, schema versioning, and efficient binary serialization for high-throughput services
- OpenAPI/Swagger (poem-openapi) — Standardized API documentation, client code generation, and contract-driven development
- Modular workspace (poem, poem-openapi, poem-grpc, poem-lambda, poem-worker) — Composable crates allow users to opt-in to features (REST-only, gRPC-only, or serverless) without bloat
⚖️Trade-offs already made
-
No unsafe Rust allowed (as per safety badge)
- Why: Maximum memory safety and auditability for production web frameworks
- Consequence: Potential minor performance overhead vs. hand-optimized unsafe code; requires robust macro-based abstractions instead
-
Separate crates for OpenAPI, gRPC, Lambda, Workers
- Why: Allows lightweight installations for simple HTTP-only use cases
- Consequence: Increased dependency fragmentation; users must coordinate versions across multiple crates
-
Compile-time route and schema generation via macros
- Why: Zero runtime reflection overhead, type safety, and compile-time validation
- Consequence: Macro complexity; errors are less intuitive; requires recompilation for route changes
-
Support HTTP/1.1, HTTP/2, and gRPC simultaneously
- Why: Enable gradual migration from REST to gRPC and multi-protocol services
- Consequence: Increased complexity in codec negotiation and streaming logic
🚫Non-goals (don't propose these)
- Does not provide built-in authentication/authorization (users integrate via middleware)
- Does not include ORM or database drivers (uses external crates like SQLx, Diesel)
- Does not offer server-side session management out-of-the-box (users implement or use third-party middleware)
- Does not handle frontend UI rendering (REST/gRPC endpoints only; clients are separate)
🪤Traps & gotchas
Workspace resolver 2 requirement: Must use Rust 1.85+ (stated as MSRV); older toolchains will fail on Cargo.lock incompatibilities. Edition 2024 usage: Some IDE/tooling support may lag; verify with rustc --version. Protobuf codegen in build.rs: gRPC examples (examples/grpc/helloworld/build.rs) invoke tonic_build, requiring protoc or equivalent in PATH—missing it silently fails during build. Unsafe-free enforced: The repo forbids any unsafe code (see README badge), so all contributions must use safe Rust—familiar to most Rustaceans but worth noting if porting from C FFI code. Sonic-rs JSON: Framework defaults to sonic-rs (faster) over serde_json for serialization in some paths; switching serializers may require feature flag tuning.
🏗️Architecture
💡Concepts to learn
- Procedural Macros (syn, quote, proc-macro2) — Poem-openapi-derive and poem-derive use compile-time code generation to transform #[get], #[post], #[derive(Schema)] annotations into boilerplate—understanding this is critical for modifying routing behavior or extending OpenAPI capabilities.
- gRPC and Protocol Buffers — poem-grpc provides first-class gRPC support via Tonic; contributors need to understand proto3 message definitions, service contracts, and code generation (build.rs + tonic_build) to maintain the gRPC integration.
- OpenAPI/Swagger Specification — poem-openapi auto-generates OpenAPI 3.0 schemas from Rust types; familiarity with OpenAPI structure (paths, schemas, security) is essential for fixing or extending documentation generation.
- Async/Await and Futures — Poem is built entirely on async/await (via Tokio); developers must understand Future trait, Pin, async function signatures, and cancellation semantics to debug performance issues or add streaming features.
- Middleware and Chain-of-Responsibility Pattern — Poem's middleware system (visible in routing examples) follows the middleware/filter pattern; understanding how requests flow through middleware layers is key to adding authentication, logging, or tracing.
- Type-Safe Extractors — Poem uses a trait-based extractor pattern (similar to FastAPI or Actix) to validate and deserialize HTTP bodies, path parameters, and headers at compile time; this is central to Poem's safety guarantee.
- JSON Schema and Schemars — poem-openapi integrates Schemars 1.0 to generate JSON Schema from Rust types; understanding how custom types derive Schema is necessary for correctly documenting complex API payloads.
🔗Related repos
tokio-rs/tokio— The async runtime foundation for Poem; understanding Tokio is essential for Poem development, especially for runtime tuning and async patterns.hyperium/hyper— HTTP/1.1 and HTTP/2 primitives layer that Poem may wrap or use internally; relevant for low-level protocol debugging.actix/actix-web— Alternative Rust web framework with similar goals (async, type-safe routing, middleware); useful for feature comparison and ecosystem cross-pollination.tonic-rs/tonic— The gRPC framework that poem-grpc builds on top of; critical dependency for gRPC service authors using Poem.serde-rs/serde— Serialization framework underlying Poem's data handling; deep understanding helps with custom serializers and OpenAPI schema generation.
🪄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 integration tests for gRPC middleware stack
The repo has a gRPC middleware example (examples/grpc/middleware/) but lacks systematic integration tests in the test suite. Given that poem-grpc is a core workspace member with middleware support, adding tests that verify middleware execution order, error handling, and context propagation across the gRPC stack would catch regressions and improve confidence in middleware composition—critical for production gRPC services.
- [ ] Review examples/grpc/middleware/src/middleware.rs to understand the middleware patterns used
- [ ] Create tests/grpc_middleware_integration_tests.rs with test cases for: middleware execution order, context propagation, error handling in middleware chains, and concurrent request isolation
- [ ] Add tests to poem-grpc/tests/ or create new integration test directory if missing, testing middleware with actual proto definitions
- [ ] Update .github/workflows/ci.yml if needed to ensure gRPC integration tests run on all PRs
Add SECURITY.md guidance and audit workflow for dependency vulnerabilities
SECURITY.md exists but is likely minimal. The repo uses many dependencies (tokio, rustls, serde, etc.) and has dependabot.yml configured. Adding a structured security policy with a GitHub Actions workflow that runs cargo-audit on each commit and generates vulnerability reports would improve supply chain security visibility—especially important for a web framework used in production.
- [ ] Review current SECURITY.md content and expand with: vulnerability reporting process, supported versions, security best practices for Poem users
- [ ] Create .github/workflows/security-audit.yml that runs cargo-audit and cargo-deny on each push to main and on PRs
- [ ] Add a section to SECURITY.md documenting the audit process and how maintainers respond to CVEs
- [ ] Document unsafe code policy (already forbidden per badge) and add unsafe code auditing steps if applicable
Add missing platform-specific tests in CI for Windows and macOS
The ci.yml workflow likely only runs on Linux. The workspace targets Rust 1.85+ across multiple platforms, but .github/workflows/ci.yml is not shown in full. Adding Windows and macOS runners to the CI matrix would catch platform-specific issues in core poem, poem-grpc, and poem-openapi that are especially critical for async/networking code where platform differences (e.g., tokio platform-specific behavior) matter.
- [ ] Examine .github/workflows/ci.yml to confirm current matrix strategy (likely Linux only)
- [ ] Extend the runs-on matrix to include: ubuntu-latest, windows-latest, macos-latest
- [ ] Add platform-specific conditional steps for any build tools that differ (e.g., protoc installation for gRPC examples)
- [ ] Verify that examples/grpc/* can compile on all platforms by including them in the CI build matrix
🌿Good first issues
- Add integration tests for poem-mcpserver with realistic Claude/LLM tool definitions; the crate exists (version 0.3.1) but examples/grpc/ lacks an MCP-specific runnable demo analogous to helloworld, making onboarding harder.
- Document or add examples for poem-lambda environment variables and cold-start optimization; poem-lambda/README.md likely lacks concrete configuration snippets for AWS_LAMBDA_RUNTIME_API and dependency size tuning, which are common pain points.
- Implement or expand poem-worker examples for background job patterns; the workspace member poem-worker/ exists but has no examples/ subdirectory, leaving users without reference implementations for task queues or delayed jobs.
⭐Top contributors
Click to expand
Top contributors
- @attila-lin — 29 commits
- @sunli829 — 28 commits
- @dependabot[bot] — 6 commits
- @0xb002f0 — 3 commits
- @luca-iachini — 3 commits
📝Recent commits
Click to expand
Recent commits
2b9056b— fix(mcpserver): fix session leak (#1181) (attila-lin)aeb85da— perf: set tcp_nodelay - disable naggle algorithm on tcp (#1177) (glebpom)98494a4— fix(mcpserver): normalize nonstandard integer formats in tool schemas (#1179) (attila-lin)9d6e245— feat(mcpserver): resource support (#1178) (attila-lin)3341f64— feat: add examples for optional/anonymous endpoint with security scheme (#1175) (ericbsantana)937dc5e— Implement ToXML for Vec<T: ToJSON> (#1173) (jbethune)5b70a0e— feat(mcpserver): update example & normalize integer unknown format likeuintuint32(#1172) (attila-lin)f53a39c— feat(mcpserver): add tracing log target to request and response (#1171) (attila-lin)2817583— fix(mcpserver): remove session when session close auto (#1170) (attila-lin)cebaefa— feat(mcpserver): supportclinetype mcp (#1167) (attila-lin)
🔒Security observations
The Poem framework demonstrates a strong security posture with several positive indicators: no unsafe code allowed, comprehensive CI/CD pipeline with code coverage tracking, explicit Rust version requirement (1.85+), and a documented security policy. However, there is a critical build configuration error (invalid edition specification) that must be fixed immediately. The vulnerability disclosure policy could be enhanced with additional contact methods and clearer response timelines. Dependency management practices appear sound with modern versions of security-critical libraries, but would benefit from automated vulnerability scanning and documented update policies. Overall, this is a well-maintained security-conscious project with minor areas for improvement.
- Medium · Edition field set to invalid year 2024 —
Cargo.toml - workspace.package section. The Cargo.toml workspace configuration specifies 'edition = "2024"', which is not a valid Rust edition. Valid editions are 2015, 2018, and 2021. This will cause compilation failures and should be corrected to a supported edition. Fix: Update 'edition = "2024"' to 'edition = "2021"' or the appropriate supported Rust edition for the project. - Low · Insufficient SECURITY.md contact information —
SECURITY.md. The SECURITY.md file provides a single email contact for vulnerability reporting. This lacks redundancy and an alternative contact method. If the primary contact is unavailable, vulnerabilities may go unreported. Fix: Add secondary contact information, establish a vulnerability disclosure program timeline/SLA, and consider publishing a PGP key for encrypted submissions. - Low · Deprecated cryptographic library versions not explicitly addressed —
Cargo.toml - workspace.dependencies (rustls, tokio-rustls). While rustls 0.23 and tokio-rustls 0.26 are reasonably current, the dependency list lacks explicit references to security advisories or MSRV (Minimum Supported Rust Version) compatibility verification for security-critical cryptographic libraries. Fix: Implement automated dependency scanning using 'cargo audit' and 'cargo-deny'. Document security update policies and establish a process for reviewing cryptographic library updates.
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.