feat: all-you-can-inline html! overhaul#4118
Merged
Madoshakalaka merged 6 commits intomasterfrom Apr 9, 2026
Merged
Conversation
match and let bindings in for bodies to html! macromatch and let bindings in for bodies to html! macro
|
Visit the preview URL for this PR (updated for commit c092e39): https://yew-rs--pr4118-feat-html-match-and-y4khdt3h.web.app (expires Thu, 16 Apr 2026 13:43:00 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 |
Size ComparisonDetails
✅ None of the examples has changed their size significantly. |
Benchmark - SSRYew MasterDetails
Pull RequestDetails
|
Madoshakalaka
commented
Apr 6, 2026
match and let bindings in for bodies to html! macro7bd1d40 to
81b0df8
Compare
78dc29c to
7956fdc
Compare
Benchmark - coreYew MasterPull Request |
aab7c90 to
675f427
Compare
- Support unbraced match arms and let bindings in match arm bodies - Support bare literals and expressions in unbraced match arms and for-loops - Support bare nodes and let bindings in if/else bodies - Support `let` bindings in `for` bodies - Automatic root fragment wrapping - Deny patterns containing unnecessarily nested `html!` macros and unnecessary fragments - Update examples to use the new syntax - Document match expressions, let bindings, and bare nodes in html!
675f427 to
5180a68
Compare
8 tasks
Madoshakalaka
commented
Apr 9, 2026
Member
Author
|
adding the performance label to trigger benchmarks as a sanity check because I touched key-related macro. |
Member
Author
2 tasks
shan-shaji
pushed a commit
to shan-shaji/yew
that referenced
this pull request
Apr 19, 2026
- Support unbraced match arms and let bindings in match arm bodies - Support bare literals and expressions in unbraced match arms and for-loops - Support bare nodes and let bindings in if/else bodies - Support `let` bindings in `for` bodies - Automatic root fragment wrapping - Protest against patterns containing unnecessarily nested `html!` macros and unnecessary fragments - Update examples to use the new syntax - Document match expressions, let bindings, and bare nodes in html!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Various macro improvements that help users write concise Yew code.
Automatic root-level fragments:
The
html!macro now accepts multiple root nodes directly:Streamlined
matcharmsPreviously,
matchrequired a block wrapper and nestedhtml!calls per arm:Now
matchworks directly, following the same pattern as the existingif/elsesupport, with let binding allowed:As shown above, match arms with a single element don't require braces:
Note, even the commas are omittable but due to users' familarity with Rust match statements, I have preserved the commas in code examples for now.
letbindings inforbodies:Previously,
letbindings insideforloops required a nested block with an innerhtml!call:Now
letbindings can appear directly before html children:letbindings must appear before any html children (not interleaved). This avoids parsing ambiguity sinceletis not a valid start for anyHtmlTreevariant. The bindings are emitted inside theIterator::for_eachclosure, scoped to each iteration.If statements let-binding and bare return node support
This now just works:
Note:
Both worked on master:
however, only the first of the two below worked:
I consider this a bug, which is fixed now.
Multi-children arms, multi-children for-loop bodies, and multi-children if-else bodies
Example:
we now protest against old patterns
Patterns like this are now hated against with a suggestion to remove the
<></>:Keyed fragments (
<key="...">) are unaffected.Patterns like this are hated against with a suggestion to remove the inner
html!:On stable, these are hard errors. On nightly, these are warnings.
I must note, these deprecation lints are vibe-coding friendly. Agents can work with a clear feedback and correct macro errors in closed loops. (note errors reported by proc_macro_error::emit_error! will batch together, unlike
compiler_error!'s early stop behavior. This will help accelerate adoption of the new syntax across user applications.That said, these lints actually increase code complexity and slow down compilation.
We can remove them X versions later, when users have caught up with the newer syntax. Then, we can remove old pattern parsing code too.
Observation
The new macro brings a 22% reduction to applicable code, as it brings real code size reduction to our examples (+443 / −565 (net −122 lines) across 38 files under examples/).
Prior Art
Focusing on some features we haven't adopted yet:
@kirillsemyonkin's yew-alt-html has a super dry syntax that allows closing tag omission and brace omission:
closing tag omission is neat because component names can become very long compared to html tags especially with genenrics.
@its-the-shrimp's yew-html-ext supports
let-elsestatments that enable early return.It also supports
cfgattributes on props and components:Checklist