yewstack/yew
Rust / Wasm framework for creating reliable and efficient web applications
Healthy across the board
Permissive 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 today
- ✓15 active contributors
- ✓Apache-2.0 licensed
Show 3 more →Show less
- ✓CI configured
- ✓Tests present
- ⚠Concentrated ownership — top contributor handles 63% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests + OpenSSF Scorecard
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/yewstack/yew)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/yewstack/yew on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: yewstack/yew
Generated by RepoPilot · 2026-05-13 · 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/yewstack/yew 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 today
- 15 active contributors
- Apache-2.0 licensed
- CI configured
- Tests present
- ⚠ Concentrated ownership — top contributor handles 63% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests + OpenSSF Scorecard</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 yewstack/yew
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/yewstack/yew.
What it runs against: a local clone of yewstack/yew — 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 yewstack/yew | 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 ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of yewstack/yew. If you don't
# have one yet, run these first:
#
# git clone https://github.com/yewstack/yew.git
# cd yew
#
# 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 yewstack/yew and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "yewstack/yew(\\.git)?\\b" \\
&& ok "origin remote is yewstack/yew" \\
|| miss "origin remote is not yewstack/yew (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 "packages" \\
&& ok "packages" \\
|| miss "missing critical file: packages"
test -f ".github/workflows/main-checks.yml" \\
&& ok ".github/workflows/main-checks.yml" \\
|| miss "missing critical file: .github/workflows/main-checks.yml"
test -f "examples" \\
&& ok "examples" \\
|| miss "missing critical file: examples"
test -f "CONTRIBUTING.md" \\
&& ok "CONTRIBUTING.md" \\
|| miss "missing critical file: CONTRIBUTING.md"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
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/yewstack/yew"
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
Yew is a Rust framework for building multi-threaded, client-side web applications that compile to WebAssembly. It provides an HTML macro syntax similar to JSX for declaring interactive UIs with Rust expressions, optimizes rendering by minimizing DOM API calls, and integrates JavaScript interoperability for leveraging NPM packages. Monorepo structure: packages/* contains core framework crates (yew-core, yew-macro), tools/* holds build tooling and CLI helpers, examples/* has runnable demo applications. The workspace uses Cargo workspaces with shared dependencies defined in [workspace.dependencies] (tokio, web-sys, wasm-bindgen). Build profiles are aggressive (LTO, single codegen unit, panic='abort') for WASM size optimization.
👥Who it's for
Rust developers building single-page web applications who want type safety and performance without JavaScript; teams migrating from React-like frameworks who prefer Rust's compile-time guarantees and are willing to compile to WASM for the browser.
🌱Maturity & risk
Yew is actively developed and production-ready. The workspace spans 1.4M lines of Rust across organized package structure (packages/*, tools/*, examples/*), multiple comprehensive workflows (.github/workflows/*), detailed API documentation infrastructure (api-docs/), and maintains strict version constraints (Rust 1.85+ requirement). The extensive CI pipeline, benchmark workflows, and website build automation indicate a mature, well-maintained project.
The project depends on fast-moving web ecosystem packages (wasm-bindgen 0.2, web-sys 0.3.70, gloo 0.12) that are outside the Yew maintainers' control; breaking changes in these dependencies directly impact stability. The single monorepo structure means issues in core packages affect all dependent crates, and WASM compilation quirks (codegen tuning, opt-level='z' for size) introduce platform-specific fragility. No red flags visible in the data, but Rust WASM ecosystem is younger than established JS frameworks.
Active areas of work
Active CI/CD pipeline with benchmark workflows (benchmark.yml, benchmark-core.yml, benchmark-ssr.yml), API documentation auto-build (build-api-docs.yml, publish-api-docs.yml), and size comparison tracking (size-cmp.yml). Website is actively maintained (build-website.yml, test-website.yml, publish-website.yml). Dependabot configured (.github/dependabot.yml) suggests dependency management is a priority. Changelog (CHANGELOG.md) and roadmap tracking (referenced in README) indicate structured release process.
🚀Get running
git clone https://github.com/yewstack/yew.git
cd yew
cargo build --release
cargo test
cargo run --example counter # runs a specific example
Daily commands:
The project uses Cargo. Start with cargo build to compile. For examples: cargo run --example <name> from root (examples are workspace members). Development: cargo test for unit tests, cargo clippy for linting (in CI as clippy.yml). The Makefile.toml suggests cargo-make tasks exist but are not listed here—check Makefile.toml for custom tasks.
🗺️Map of the codebase
Cargo.toml— Workspace root configuration defining all member packages, Rust version requirements (1.85+), and critical build profiles for release and benchmarking.packages— Core Yew framework packages directory containing the main component system, hooks, routing, and virtual DOM implementation..github/workflows/main-checks.yml— Primary CI/CD pipeline enforcing test, clippy, and fmt checks on all pull requests before merge.examples— Example applications demonstrating Yew patterns and serving as integration tests for the framework's public API.CONTRIBUTING.md— Developer guide outlining contribution workflows, code standards, and testing requirements specific to this Rust/Wasm framework.README.md— Project overview describing Yew as a Rust/Wasm client web framework with links to documentation and roadmap.
🛠️How to make changes
Add a new example demonstrating a Yew pattern
- Create new example directory with Cargo.toml inheriting workspace dependencies (
examples/your_example/Cargo.toml) - Implement main component in src/main.rs following Yew functional component with #[function_component] macro (
examples/your_example/src/main.rs) - Add HTML entry point with target div for Yew to hydrate (
examples/your_example/index.html) - Create Trunk.toml if using Trunk bundler, or reference parent Cargo.toml if using workspace build (
examples/your_example/Trunk.toml) - Document the pattern with README.md explaining the example's learning objectives (
examples/your_example/README.md)
Add a new feature to the core framework
- Define feature gate in packages/yew/Cargo.toml under [features] (
packages/yew/Cargo.toml) - Implement feature logic with #[cfg(feature = "your_feature")] conditionals (
packages/yew/src/lib.rs) - Add integration test demonstrating feature in examples/ or packages/tests/ (
examples/your_feature_demo/src/main.rs) - Document feature usage in inline rustdoc comments and update CHANGELOG.md (
CHANGELOG.md) - Run main-checks workflow to ensure clippy, fmt, and tests pass (
.github/workflows/main-checks.yml)
Debug performance regressions detected by benchmarks
- Review benchmark results in .github/workflows/benchmark.yml and post-benchmark.yml outputs (
.github/workflows/post-benchmark.yml) - Run local benchmarks using Makefile.toml task runners (
Makefile.toml) - Profile with cargo flamegraph or cachegrind on the affected package (e.g., packages/yew-core) (
packages) - Examine release profile optimization in Cargo.toml (lto=true, opt-level=z for size or opt-level=3 for bench) (
Cargo.toml) - Add regression test to examples/ ensuring the performance characteristic is maintained (
examples)
🔧Why these technologies
- Rust + WebAssembly — Provides type safety, memory safety without garbage collection, and near-native performance for browser applications; eliminating entire classes of bugs common in JavaScript.
- wasm-bindgen — Seamlessly bridges Rust WebAssembly and JavaScript APIs, enabling DOM manipulation and interop with web browser APIs without manual FFI boilerplate.
- Procedural macros (syn, quote, proc-macro2) — Powers the #[function_component], #[derive], and #[html!] macros that make Yew's DSL ergonomic and reduce boilerplate component definition.
- Tokio for async — Provides futures-based async/await runtime for handling side effects (API calls, timers) alongside component lifecycle in a non-blocking manner.
- LTO + opt-level=z (release profile) — Minimizes final WebAssembly bundle size by enabling Link-Time Optimization and aggressive dead-code elimination, critical for client-side web delivery.
⚖️Trade-offs already made
-
Compile-time rendering via macros vs. runtime template evaluation
- Why: Macro-based #[html!] macro enforces type safety at compile time and eliminates runtime parsing overhead, but requires recompilation for template changes.
- Consequence: Faster execution and zero runtime bugs from malformed templates, but slower development iteration if heavy template changes are frequent.
-
Virtual DOM diffing vs. fine-grained reactivity (signals)
- Why: Virtual DOM is conceptually simpler and proven in other frameworks (React), but requires entire subtree re-render on any state change even if data path is narrow.
- Consequence: Easier to reason about rendering, but can be less efficient than frameworks with granular change tracking; mitigated by memoization strategies.
-
Workspace with multiple publishable packages vs. monolithic crate
- Why: Allows yew-router, yew-html, and other modules to evolve and version independently while sharing core yew infrastructure.
- Consequence: More complex dependency management and coordination across releases, but enables cleaner module boundaries and selective adoption.
-
Server-side rendering (SSR) examples via Actix-web + Axum vs. built-in SSR support
- Why: Framework remains agnostic to backend, demonstrating patterns rather than enforcing a specific server framework.
- Consequence: Users must wire SSR themselves, but retain full control over server choice and performance tuning; less lock-in.
🚫Non-goals (don't propose these)
- Does not provide a built-in state management library; users select Redux-like or Context-based patterns independently.
- Does not handle server-side rendering out-of-the-box; SSR requires integrating with external backend frameworks (Actix, Axum, etc.).
- Does not enforce a specific routing library; yew-router is optional and separate.
- Does not provide database integrations or ORM bindings; data fetching is left to async tasks and HTTP clients.
- Does not support older browsers or non-WebAssembly JavaScript runtimes; targets modern browsers with full Wasm support.
- Not a replacement for CSS frameworks; Yew outputs raw HTML/CSS and leaves styling to Tailwind, Bootstrap, or custom CSS.
🪤Traps & gotchas
WASM-specific build configuration in .cargo/config.toml may enforce wasm32-unknown-unknown target automatically—verify before trying to build for native. The aggressive release profile (opt-level='z', panic='abort') makes unwinding difficult in WASM; panics abort instead. Rust version pinned to 1.85+, so older toolchains will fail. The workspace uses resolver='3' which is recent (2021 edition+)—check MSRV if you're on an older Rust. No explicit environment variables required, but examples may need cargo-run to handle WASM target discovery.
🏗️Architecture
💡Concepts to learn
- Virtual DOM (VDOM) — Yew uses VDOM diffing to minimize expensive browser DOM API calls; understanding the diffing algorithm is key to optimizing component rendering performance.
- WebAssembly (WASM) — Yew compiles Rust to WASM bytecode for browser execution; you must understand WASM's sandbox model, memory layout, and JS interop boundaries to debug runtime issues.
- Procedural Macros (proc-macros) — The
html!macro (inpackages/yew-macro/) is a procedural macro that transforms JSX-like syntax at compile time; modifying the framework's syntax requires understanding proc-macro mechanics. - Component Lifecycle & Hooks — Yew components follow React-like patterns (props, state, lifecycle); Yew's hooks (UseState, UseEffect, UseContext) are essential abstractions for managing component behavior.
- Message-Passing Concurrency — Yew uses Tokio-based channels for inter-component communication; understanding async message passing is vital for building responsive, non-blocking UIs.
- Link Reduction (Binary Size Optimization) — The aggressive release profile (LTO, opt-level='z', panic='abort', codegen-units=1) is tuned to minimize WASM binary size; this is critical because WASM bundles are downloaded by users.
- FFI (Foreign Function Interface) with JS — Yew depends on wasm-bindgen for JS interop (web-sys for DOM, js-sys for JS objects); you must know how to marshal data across the Rust-JS boundary to integrate with external JS libraries.
🔗Related repos
leptos-rs/leptos— Alternative Rust WASM framework emphasizing fine-grained reactivity over virtual DOM; directly competes with Yew for the same developer audience.dioxus-labs/dioxus— Another Rust WASM UI framework with React-inspired syntax; growing alternative to Yew with slightly different design philosophy (hooks-first).rustwasm/wasm-bindgen— Foundational Rust-WASM interop library that Yew depends on (wasm-bindgen = '0.2'in workspace.dependencies); understanding this is critical for Yew's JS FFI.gfx-rs/gfx— Rust graphics abstraction used in advanced Yew examples for rendering; relevant for developers building graphics-intensive Yew applications.yewstack/yew-router— Official Yew companion library for client-side routing; commonly paired with Yew for SPA navigation (likely in examples or docs).
🪄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 E2E tests for SSR examples (actix_ssr_router)
The actix_ssr_router example has a basic e2e.rs test file, but examining the repo structure shows multiple SSR-related workflows (benchmark-ssr.yml, post-benchmark-ssr.yml) with no corresponding comprehensive E2E test suite. Contributors could expand testing coverage for server-side rendering scenarios, hydration verification, and router functionality to catch regressions early.
- [ ] Review examples/actix_ssr_router/tests/e2e.rs and identify missing test scenarios
- [ ] Add tests for hydration verification (comparing server-rendered HTML with client-hydrated state)
- [ ] Add tests for router functionality across SSR boundaries (navigation, state persistence)
- [ ] Add tests for async operations during SSR (data fetching, initialization)
- [ ] Ensure tests run in CI by checking .github/workflows/main-checks.yml includes SSR test invocation
Add missing unit tests for workspace lints configuration
The Cargo.toml defines custom lints (cfg(documenting), cfg(verbose_tests), cfg(yew_lints), cfg(nightly_yew), cfg(wasm_bindgen_unstable_test_coverage)) but there's no dedicated test suite validating these lint configurations are applied correctly across packages. Contributors could create a lints validation test to ensure custom cfg attributes work as intended.
- [ ] Create packages/yew-core/tests/lint_config_test.rs (or similar) to verify custom cfg flags are recognized
- [ ] Add tests validating that cfg(yew_lints) gates appropriate linting rules
- [ ] Add trybuild tests to verify macro expansion under different cfg configurations
- [ ] Document the purpose of each custom lint in CONTRIBUTING.md with examples
- [ ] Ensure test runs in main-checks.yml workflow
Implement missing CI workflow for MSRV (Minimum Supported Rust Version) validation
Cargo.toml specifies rust-version = "1.85" as MSRV, but there's no dedicated CI workflow to validate compilation against this exact version. This is critical for library maintainers to prevent accidentally breaking MSRV compatibility. A new workflow would test all workspace members and examples against Rust 1.85.
- [ ] Create .github/workflows/msrv-check.yml that installs Rust 1.85 and runs 'cargo check' for all workspace members
- [ ] Include both 'cargo build' and 'cargo test --no-run' to catch compile-time failures
- [ ] Add MSRV check to main-checks.yml as a required status check
- [ ] Test against examples directory (examples/.cargo/config.toml may have special handling)
- [ ] Document MSRV policy in CONTRIBUTING.md with link to workflow
🌿Good first issues
- Add integration tests for the html! macro in
packages/yew-macro/tests/covering edge cases like nested attribute interpolation, conditional rendering in attributes, and tuple spreading—currently sparse. - Expand documentation in
website/docsfor the hooks API (UseState, UseEffect, UseContext) with runnable example snippets inexamples/, mirroring React hooks patterns. - Create a minimal SSR (Server-Side Rendering) example in
examples/demonstrating how to use Yew with the existingbenchmark-ssr.ymlpipeline as reference—SSR support exists but examples are sparse.
⭐Top contributors
Click to expand
Top contributors
- @Madoshakalaka — 63 commits
- @dependabot[bot] — 15 commits
- @GitHub-Action — 7 commits
- @WorldSEnder — 3 commits
- @rmschindler — 2 commits
📝Recent commits
Click to expand
Recent commits
d9cd31f— chore(examples): bump nanoid to 0.5 and propagate getrandom wasm_js (#4155) (Madoshakalaka)b50f17f— chore: update NO_TRUNK_EXAMPLES for renamed SSR examples (#4154) (Madoshakalaka)c28846c— Validate attribute names (#4152) (WorldSEnder)3421117— feat(yew-macro): auto-detect imperative for/while/loop in preamble (#4146) (Madoshakalaka)d4e5e9f— feat: while, break/continue/return, and preamble statements in html! (#4124) (Madoshakalaka)7085ad3— chore(deps): bump rustls-webpki from 0.103.10 to 0.103.13 (#4143) (dependabot[bot])4021951— fix inconsistent effects for suspended nodes (#3991) (Madoshakalaka)28219ae— fix(website): unversion migration guides (#4139) (Madoshakalaka)a259eae— chore(yew-macro): remove orphan html-component-fail.stderr (#4140) (Madoshakalaka)b814bf6— fix(website): correct trunk urls - now hosted on github.io (#4138) (Madoshakalaka)
🔒Security observations
The Yew framework codebase demonstrates generally good security practices with LTO hardening, dependency pinning, and a formal security reporting policy. However, there are moderate concerns around outdated dependencies (actix-web <4.13), use of prerelease versions (bincode), and lack of documented web security header guidance for framework users. The codebase itself shows no obvious injection vulnerabilities or hardcoded credentials in the analyzed structure. The primary risks are dependency-related and operational (missing security header documentation). The security posture is acceptable for an active open-source project but should address the actix-web version constraint and bincode prerelease dependency.
- Medium · Outdated actix-web Dependency with Known Vulnerabilities —
Cargo.toml - workspace.dependencies. The workspace uses actix-web '<4.13' due to rustc version constraints. Version 4.12 and earlier may contain known security vulnerabilities. The constraint 'rustc > 1.85' prevents use of patched versions. Fix: Monitor actix-web security advisories. Consider upgrading rust-version requirement in workspace.package to allow newer actix-web versions, or evaluate alternative web frameworks with better version compatibility. - Medium · Prerelease bincode Dependency —
Cargo.toml - workspace.dependencies. The codebase uses bincode '2.0.0-rc.3', a release candidate version. RC versions are not production-ready and may contain bugs or security issues before final release. Fix: Upgrade to the stable 2.0.0 release of bincode once available, or document the rationale for using a prerelease version and establish a timeline for upgrading. - Low · Missing Web Security Headers Configuration —
Build configuration and example applications. No evidence of security header configuration (CSP, X-Frame-Options, X-Content-Type-Options, etc.) in build pipeline or example configurations. This is particularly important for a web framework. Fix: Add documentation and examples demonstrating proper security header configuration for applications built with Yew. Include CSP policy recommendations for WebAssembly applications. - Low · Firebase Configuration File Detected —
.firebaserc. Presence of '.firebaserc' file in repository root. While typically not containing secrets, it indicates Firebase integration and should be monitored to ensure no credentials are accidentally committed. Fix: Verify .firebaserc contains only non-sensitive configuration. Add to documentation any Firebase security best practices. Use environment-based configuration for sensitive Firebase credentials. - Low · LTO and Single Codegen Unit Release Config May Impact Debuggability —
Cargo.toml - profile.release. Release profile uses 'lto = true' and 'codegen-units = 1' with 'panic = abort'. While this improves security through optimization, it reduces debugging capabilities in production incidents. Fix: Document the security/debuggability tradeoff. Consider providing separate debug symbol configurations for post-mortem analysis while maintaining the hardened release profile.
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.