flosse/rust-web-framework-comparison
A comparison of some web frameworks and libs written in Rust
Missing license — unclear to depend on
weakest axisno license — legally unclear; no tests detected…
no license — can't legally use code; no tests detected…
Documented and popular — useful reference codebase to read through.
no license — can't legally use code; no CI workflows detected
- ✓Last commit 3w ago
- ✓23+ active contributors
- ⚠Concentrated ownership — top contributor handles 66% of recent commits
Show all 6 evidence items →Show less
- ⚠No license — legally unclear to depend on
- ⚠No CI workflows detected
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Concerns → Mixed if: publish a permissive license (MIT, Apache-2.0, etc.)
- →Fork & modify Concerns → Mixed if: add a LICENSE file
- →Deploy as-is Concerns → Mixed if: add a LICENSE file
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 "Great to learn from" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/flosse/rust-web-framework-comparison)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/flosse/rust-web-framework-comparison on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: flosse/rust-web-framework-comparison
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/flosse/rust-web-framework-comparison 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
WAIT — Missing license — unclear to depend on
- Last commit 3w ago
- 23+ active contributors
- ⚠ Concentrated ownership — top contributor handles 66% of recent commits
- ⚠ No license — legally unclear to depend on
- ⚠ No CI workflows detected
- ⚠ No test directory detected
<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 flosse/rust-web-framework-comparison
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/flosse/rust-web-framework-comparison.
What it runs against: a local clone of flosse/rust-web-framework-comparison — 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 flosse/rust-web-framework-comparison | Confirms the artifact applies here, not a fork |
| 2 | Default branch master exists | Catches branch renames |
| 3 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 4 | Last commit ≤ 48 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of flosse/rust-web-framework-comparison. If you don't
# have one yet, run these first:
#
# git clone https://github.com/flosse/rust-web-framework-comparison.git
# cd rust-web-framework-comparison
#
# 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 flosse/rust-web-framework-comparison and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "flosse/rust-web-framework-comparison(\\.git)?\\b" \\
&& ok "origin remote is flosse/rust-web-framework-comparison" \\
|| miss "origin remote is not flosse/rust-web-framework-comparison (artifact may be from a fork)"
# 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 "src/main.rs" \\
&& ok "src/main.rs" \\
|| miss "missing critical file: src/main.rs"
test -f "data.toml" \\
&& ok "data.toml" \\
|| miss "missing critical file: data.toml"
test -f "src/data.rs" \\
&& ok "src/data.rs" \\
|| miss "missing critical file: src/data.rs"
test -f "src/table.rs" \\
&& ok "src/table.rs" \\
|| miss "missing critical file: src/table.rs"
test -f "Cargo.toml" \\
&& ok "Cargo.toml" \\
|| miss "missing critical file: 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 48 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~18d)"
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/flosse/rust-web-framework-comparison"
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
A static documentation site generator that scrapes metadata (GitHub stars, contributors, activity, downloads, license, version) for ~100+ Rust web frameworks and libraries, then renders comparison tables in markdown format via Tera templates. The core problem it solves: keeping an up-to-date, searchable comparison of Rust web frameworks across multiple categories (WASM frontends, server frameworks, templating, WebSockets) without manual maintenance. Simple single-binary structure: src/main.rs orchestrates the pipeline, src/data.rs handles fetching GitHub/crates.io metadata using reqwest and crates_io_api, src/table.rs formats the fetched data into markdown table rows using Tera templates, and data.toml (the configuration) defines all frameworks/libraries to track by category. Output is a rendered README.md generated from README.tmpl via Tera.
👥Who it's for
Rust developers evaluating web frameworks for a new project, technical blog authors creating framework comparison posts, and Rust ecosystem maintainers who want a canonical reference for framework landscape across multiple paradigms (frontend/backend/client/templating).
🌱Maturity & risk
Early-stage but actively maintained utility: the repo is lightweight (~18KB Rust code), uses stable Rust only, has minimal dependencies (10 total), and appears designed as a one-off documentation generator rather than a production application. No visible test suite or CI pipeline in the file list; maturity is 'documentation tool, not production library'—suitable for maintaining comparison docs but not production-critical.
Low risk overall due to minimal scope and dependencies. Main risks: (1) the GitHub API and crates.io API calls in src/data.rs may rate-limit or break if those services change their response format, (2) reqwest dependency on rustls-tls could have security implications if not updated regularly, (3) the data.toml file is the single source of truth for framework metadata—corruption or staleness is a single point of failure, (4) no automated testing means framework additions could introduce typos or broken URLs silently.
Active areas of work
The repository appears to be in maintenance mode for documentation updates: no specific active development visible in the file list, but the tool itself is designed to be run periodically to refresh framework metadata (stars, contributors, download counts) in the comparison tables. Recent updates likely involve adding newly-released frameworks to data.toml or updating category sections.
🚀Get running
git clone https://github.com/flosse/rust-web-framework-comparison.git
cd rust-web-framework-comparison
cargo build --release
cargo run --release
This will fetch live metadata and regenerate README.md.
Daily commands:
cargo run --release
No dev server; this is a one-shot generator. Generates README.md by reading data.toml, fetching live GitHub/crates.io stats, and rendering via README.tmpl.
🗺️Map of the codebase
src/main.rs— Entry point that orchestrates data loading, processing, and README generation—every contributor must understand the overall flow.data.toml— Central data source defining all frameworks, libraries, and their metadata that drive the comparison table—the source of truth for the repo's content.src/data.rs— Deserialization and data structure definitions for frameworks and features—critical for understanding how toml data maps to Rust types.src/table.rs— Table rendering logic that transforms framework data into markdown—core logic for generating the comparison output.Cargo.toml— Dependency declarations including tera templating, reqwest for HTTP, and crates_io_api for fetching live framework data.README.tmpl— Tera template that combines static content with dynamic framework tables—defines the output structure and layout.
🧩Components & responsibilities
- main.rs (env_logger, anyhow, std::fs, reqwest) — Orchestrates entire pipeline: loads config, fetches API data, invokes rendering, writes output
- Failure mode: Network timeout or API unavailability halts README generation; can retry or use stale data fallback
- data.rs (serde, url) — Defines and deserializes all domain types (Framework, Feature, Category, Link) from TOML
- Failure mode: Schema mismatch in data.toml causes deserialization panic; caught at runtime with anyhow
- table.rs (pad crate for column alignment) — Formats and aligns framework data into readable markdown tables
- Failure mode: Misaligned or truncated columns if data contains unexpected sizes; recovers by padding or wrapping
- README.tmpl (Tera templating) — Tera template that defines README structure and injects dynamic framework tables
- Failure mode: Missing template variables or syntax errors prevent rendering; caught by Tera engine
🔀Data flow
data.toml→data.rs deserialization— TOML file parsed into Framework, Feature, Category structsdata.rs→main.rs— Deserialized framework list passed to orchestratormain.rs→crates.io API— Framework repository URLs sent to fetch live stars and contributor countscrates.io API→main.rs— Metadata merged back into framework structsmain.rs→table.rs— Framework data grouped by category sent for table renderingtable.rs→main.rs— Rendered markdown tables returned as stringsmain.rs→README.tmpl (Tera)— Tables and metadata injected into template contextREADME.tmpl→README.md— Final rendered markdown written to output file
🛠️How to make changes
Add a new web framework to the comparison
- Define the framework in data.toml under the appropriate category (Frontend, HighLevel, LowLevel, etc.) with name, repository, and features (
data.toml) - Ensure the framework struct in src/data.rs matches the TOML schema (name, url, github_url, stars, contributors fields) (
src/data.rs) - Run main.rs which will fetch framework metadata from crates.io and regenerate README.md with the new entry (
src/main.rs)
Update the comparison table columns or layout
- Modify the Feature enum in src/data.rs to add or remove columns from the comparison (
src/data.rs) - Update table rendering logic in src/table.rs to handle the new feature columns (
src/table.rs) - Re-run main.rs to regenerate the README with updated table structure (
src/main.rs)
Customize the README structure or styling
- Edit README.tmpl to reorganize sections, change headers, or adjust template variables (
README.tmpl) - Verify tera template syntax and variable bindings match the data structures defined in src/data.rs (
src/data.rs) - Run main.rs to render the new template and generate updated README.md (
src/main.rs)
🔧Why these technologies
- Tera templating — Enables clean separation of static markdown content from dynamic framework table injection without manual string concatenation
- reqwest + crates_io_api — Provides live fetching of framework metadata (stars, contributors) from crates.io to keep comparison data current
- TOML data format — Human-readable config format optimized for defining structured framework catalogs with feature matrices and relationships
- Serde for deserialization — Type-safe, efficient conversion of TOML into Rust structs with compile-time correctness guarantees
⚖️Trade-offs already made
-
Runtime crates.io API calls for framework metadata
- Why: Keeps star counts and contributor data fresh without manual updates
- Consequence: Generation time depends on network latency and API availability; no offline-first operation possible
-
Single data.toml as source of truth
- Why: Simplifies maintenance and ensures consistency across all categories
- Consequence: No distributed or database-backed configuration; large catalogs could become unwieldy in a single file
-
Markdown output only (no interactive HTML)
- Why: Focuses on GitHub-native comparisons for maximum portability and simplicity
- Consequence: No filtering, sorting, or interactivity in generated documentation
🚫Non-goals (don't propose these)
- Does not provide real-time framework discovery or automated crate detection—all frameworks manually curated
- Does not generate interactive dashboards or web UIs—output is static markdown only
- Does not track historical trends or version changes—stores only latest snapshot
- Does not perform automated benchmarking or performance testing—metrics are manually sourced
📊Code metrics
- Avg cyclomatic complexity: ~2 — Small, focused codebase with linear data pipeline: load → fetch → render → write
⚠️Anti-patterns to avoid
- Blocking HTTP calls on main thread (Medium) —
src/main.rs: Uses reqwest::blocking to make synchronous crates.io API calls; scales poorly with framework count and network latency. Could use async/await or thread pool for parallelism. - No caching of API responses (Low) —
src/main.rs: Fetches framework metadata every run without local cache; causes unnecessary API calls and generation latency. Could cache responses with TTL. - Hard-coded category ordering (Low) —
src/table.rs, README.tmpl: Category display order is implicit in template structure rather than data-driven; difficult to reorder without code changes.
🔥Performance hotspots
main.rs crates.io API calls(I/O bound) — Network requests to fetch framework metadata for each entry; can take 100–500ms per batch depending on API rate limits and latency. Sequential requests block progress.Tera template rendering(CPU bound) — Dynamic table injection and variable substitution across entire README template can be slow for large framework catalogs (100+ entries).
🪤Traps & gotchas
GitHub API rate limiting: src/data.rs makes HTTP calls to github.com/api/v3 without visible authentication/token handling—may hit 60 req/hour unauthenticated limit if regenerating frequently. Add GITHUB_TOKEN env var for higher limits. data.toml format: uses TOML inline table syntax ([[frontend]] arrays)—typos in package names or GitHub URLs silently fail to fetch metadata and render as blank cells. Tera template errors: broken syntax in README.tmpl will cause panic at runtime with unhelpful error messages. No offline mode: tool requires live internet to fetch GitHub and crates.io; cannot regenerate without network.
🏗️Architecture
💡Concepts to learn
- Web framework landscape stratification — This repo categorizes frameworks by abstraction level (high-level server, low-level, WASM frontend, templating, WebSocket libraries)—understanding why Axum differs from Hyper or why Leptos is separate from Yew requires grasping that Rust web dev spans multiple concerns without a monolithic 'Rails equivalent'
- GitHub API data scraping & rate limiting — src/data.rs fetches live GitHub stats (stars, contributors, last commit activity) via unauthenticated API calls—contributors must understand rate limits, pagination, and authentication tokens to avoid silent failures during data refresh
- Tera templating & jinja2 syntax — README.tmpl is rendered by Tera (Rust's Jinja2 port); modifying table structure or adding new columns requires templating skills beyond basic markdown
- Crates.io API metadata fields — src/data.rs parses download counts and version info from crates.io; knowing which fields are optional vs. required (and how to handle missing data) is critical for preventing panics during framework metadata collection
- TOML configuration format & array of tables syntax — data.toml uses
[[category]]syntax to define framework lists; misconfiguring this breaks the entire data pipeline silently, making it a common source of contributor errors - Markdown table generation & escaping — src/table.rs must escape pipe characters
|in framework names and URLs to avoid breaking markdown table syntax—subtle escaping bugs lead to malformed comparison tables - Reqwest blocking vs. async HTTP clients — Cargo.toml uses reqwest with 'blocking' feature (synchronous), not async—understanding why blocking is chosen here (single-threaded generator, not server) informs when to use sync vs. async in Rust web projects
🔗Related repos
tensorflow/ecosystem— Parallel concept: a curated matrix comparing libraries in an ecosystem (TensorFlow-adjacent ML frameworks) with GitHub metadata—same 'comparison table generator' patternawesome-rust/awesome-rust— Ecosystem sibling: manually curated list of Rust crates; this repo automates that curation for web frameworks specifically with live dataactix/actix-web— A primary subject framework (appears in data.toml); understanding actix's architecture helps explain why this comparison tool exists—to demystify options like ittokio-rs/tokio— Async runtime that powers most server frameworks in data.toml; knowing tokio is essential context for why comparison matters (most frameworks depend on it)rust-lang/crates.io— Data source: crates_io_api calls this API; understanding its response format helps debug metadata fetch failures in src/data.rs
🪄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 automated data validation tests for data.toml entries
The repo relies on data.toml as its source of truth for framework comparisons, but there are no tests validating the structure and content. New contributors could add a test suite in src/main.rs or a new src/tests.rs module that verifies each framework entry has required fields (name, url, etc.), valid URLs, and no duplicates. This prevents data quality issues from being merged.
- [ ] Create src/tests.rs with unit tests using #[cfg(test)]
- [ ] Parse data.toml and validate all framework entries have required fields
- [ ] Add tests to check for duplicate framework names and URLs
- [ ] Verify URL format using the existing url crate dependency
- [ ] Run tests in CI by updating Cargo.toml test configuration if needed
Add GitHub Actions workflow to validate data.toml on pull requests
Currently, there's no automated validation preventing malformed data.toml changes from being merged. A new contributor could create .github/workflows/validate-data.yml that runs the existing Rust binary (src/main.rs) or a dedicated validation script to catch formatting errors, missing fields, or stale framework data before review.
- [ ] Create .github/workflows/validate-data.yml workflow file
- [ ] Configure workflow to run on pull_request events targeting README.md and data.toml
- [ ] Add step to run 'cargo test' to execute data.toml validation
- [ ] Optionally add step to verify README.md is regenerated from README.tmpl and data.toml
Refactor data.rs to add strongly-typed validation layer for framework entries
The src/data.rs file currently deserializes data.toml with serde, but there's likely minimal validation beyond TOML parsing. A new contributor could extend the data structures in src/data.rs with custom deserializers and validation methods (e.g., validate_url(), validate_framework_name()) to catch issues at deserialization time rather than during template rendering.
- [ ] Review current struct definitions in src/data.rs for Framework, Category, etc.
- [ ] Add custom #[serde(deserialize_with = "...")] attributes for URL and name fields
- [ ] Implement validator functions using anyhow::Result for better error messages
- [ ] Add tests in src/data.rs testing deserialization of valid and invalid framework entries
- [ ] Update src/main.rs to leverage the new validation layer during data loading
🌿Good first issues
- Add a GitHub Actions CI workflow (.github/workflows/update.yml) to regenerate README.md nightly and commit changes, solving the staleness problem; this requires understanding Tera templating output and git automation
- Create src/test.rs with unit tests for src/table.rs markdown escaping (test that framework names with pipes
|or backticks don't break table rendering) and for src/data.rs JSON parsing edge cases (empty contributor counts, missing license fields) - Document in CONTRIBUTING.md the exact steps to add a new framework to data.toml, including GitHub URL format validation rules and how to test locally before submitting PR—currently undocumented, causing contributor friction
⭐Top contributors
Click to expand
Top contributors
- @flosse — 66 commits
- @kanarus — 5 commits
- @SamuelBonilla — 4 commits
- @Kijewski — 2 commits
- @jtwaleson — 2 commits
📝Recent commits
Click to expand
Recent commits
5218524— Replace actix-web-actors with actix-ws (JohnTitor)92aedaf— Mark iced as up-to-date again (flosse)41d147a— Add rshtml to templating comparison (mehmetkesik)2f22913— Added Xilem Web (flosse)9b27c3c— Mark yew as active again (flosse)924dbdc— Update (flosse)e795165— Add cot backend framework (m4tx)3678d7f— Mark dominator as outdated (flosse)b56bf56— Add natrix frontend framework (flosse)240740f— Removerinja, update data, and add missing data (#187) (Kijewski)
🔒Security observations
This Rust web framework comparison project has a generally secure dependency profile. The codebase uses modern, security-conscious libraries (Rustls for TLS, Serde for serialization). No critical vulnerabilities detected. Minor concerns include outdated 'pad' crate and potential XSS risks if template auto-escaping is misconfigured. The project appears to be a documentation/comparison tool rather than a production web service, which reduces overall risk. No hardcoded secrets, exposed ports, or obvious injection vulnerabilities were identified in the provided files. Regular dependency updates and code review of template rendering practices are recommended.
- Low · Outdated dependency: pad 0.1 —
Cargo.toml - pad dependency. The 'pad' crate version 0.1 is significantly outdated. While not a known critical vulnerability, older versions may lack security patches and bug fixes. The crate appears to be unmaintained based on its age. Fix: Update to the latest version of 'pad' or consider replacing with actively maintained alternatives. If not critical to functionality, consider removing the dependency. - Low · Permissive reqwest TLS configuration —
Cargo.toml - reqwest dependency. The reqwest dependency uses 'rustls-tls' feature with default settings. While Rustls is generally secure, ensure that certificate validation is not disabled elsewhere in the codebase when making HTTPS requests. Fix: Verify that all HTTPS requests in src/main.rs and related files properly validate TLS certificates. Do not disable certificate verification for any requests, especially to external APIs. - Low · Template rendering with Tera —
Cargo.toml - tera dependency; src/table.rs (likely template usage). The codebase uses Tera templating engine. While Tera provides auto-escaping by default, XSS vulnerabilities are possible if auto-escaping is disabled or if user input is marked as 'safe' without proper sanitization. Fix: Ensure auto-escaping is enabled in Tera configuration. Never mark user-controlled input as safe/unescaped. Validate and sanitize all external data before rendering templates.
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.