diff --git a/active-rfcs/0046-patterned-template.md b/active-rfcs/0046-patterned-template.md
new file mode 100644
index 00000000..6363515a
--- /dev/null
+++ b/active-rfcs/0046-patterned-template.md
@@ -0,0 +1,784 @@
+- Start Date: 2026-03-05
+- Target Major Version: ?
+- Reference Issues: N/A
+- Implementation PRs (Draft reference implementation): [compiler / SSR / Vapor](https://github.com/vuejs/core/pull/15531), [language-tools](https://github.com/vuejs/language-tools/pull/6207), [docs](https://github.com/vuejs/docs/pull/3465)
+
+# Summary
+
+Introduce `v-match` and `v-when` for declarative pattern-based conditional rendering in Vue templates.
+
+`v-match` evaluates a subject expression once. Each direct `v-when` child declares a pattern, optional bindings (including object and array rest), and an optional guard. Branches are checked from top to bottom, only the first matching branch renders, and no fallthrough is possible. Template type checking requires exhaustive coverage, with `_` available as the fallback pattern.
+
+The initial syntax keeps `v-when` in its long form. Shorthand candidates and their trade-offs are recorded below for future discussion.
+
+The proposed syntax intentionally follows the vocabulary of the TC39 ECMAScript Pattern Matching proposal (`match` / `when`, pattern guards, declaration bindings) while also catching up with Flow's shipped `match` feature (`const` variable declaration patterns, `if` guards, `_` wildcard, `|` alternatives, `as` bindings, and exhaustiveness-aware tooling).
+
+# Basic example
+
+```vue
+
+
+
+
+
+
+
+
+
+
+ Unknown result.
+
+```
+
+The above is equivalent in behavior to a `v-if` / `v-else-if` chain that first evaluates `result`, checks each branch in order, introduces branch-local template bindings such as `article` and `error`, and renders the fallback only if no previous branch matched.
+
+# Motivation
+
+## Chained `v-if` is repetitive for one subject
+
+When rendering different content based on a single reactive value, developers currently repeat the same expression in every branch:
+
+```vue
+
+
+
+
+
+ Unknown result.
+
+```
+
+This has several drawbacks:
+
+1. The discriminant expression is repeated in every branch.
+2. Branches that conceptually belong to one match are only implicitly grouped by adjacency.
+3. Nested data has to be re-addressed manually instead of being bound where it is matched.
+4. Type tooling has to recover intent from arbitrary boolean expressions.
+
+`v-match` makes the subject explicit, and `v-when` makes each branch an arm of the same match.
+
+## Vue code increasingly models UI state as tagged data
+
+Vue applications commonly consume typed state from composables, loaders, data-fetching libraries, state stores, routers, and RPC clients. These values are often modeled as discriminated unions or tagged objects:
+
+```ts
+type RemoteData =
+ | { status: 'idle' }
+ | { status: 'loading' }
+ | { status: 'success'; data: T }
+ | { status: 'error'; error: E }
+```
+
+Templates need an ergonomic way to render these states without repeatedly indexing into the same object and without losing branch-specific type information.
+
+## Prior art is converging on patterns plus bindings
+
+- The [TC39 ECMAScript Pattern Matching proposal](https://github.com/tc39/proposal-pattern-matching) uses `match` expressions with `when` arms, declaration patterns such as `const status`, rest binding patterns, and guard patterns.
+- [Flow's `match`](https://flow.org/en/docs/match/) has shipped with object, array, wildcard, `const`, `|`, `as`, instance, guard, exhaustiveness, and unused-pattern checks.
+- Rust, Swift, Kotlin, Scala, F#, Python, and Elixir all demonstrate that pattern matching is most valuable when it can both test a shape and bind useful parts of the matched value.
+
+This RFC does not attempt to add JavaScript pattern matching to Vue. It proposes a template-level feature that borrows the parts that map cleanly to rendering: arm syntax, structural patterns, branch-local bindings, guard conditions, and type-tooling hooks.
+
+# Detailed design
+
+## Recommended syntax: `v-match` / `v-when`
+
+```html
+
+ ...
+ ...
+ ...
+
+```
+
+- `v-match` evaluates the subject expression.
+- `v-when` declares a pattern arm.
+- `v-when="_"` declares an unconditional fallback arm.
+- An optional `if ()` suffix acts as a branch guard.
+
+The name `v-when` is recommended over the previous `v-case` direction because it directly mirrors TC39's `match (...) { when ... }` vocabulary and avoids suggesting JavaScript `switch` fallthrough behavior.
+
+## SFC top-level template
+
+An SFC may place `v-match` directly on its top-level ``, as in the basic example. It is equivalent to a plain SFC `` containing one inner `` around the entire template content. No extra DOM wrapper is introduced.
+
+The subject resolves in the component's template scope. Direct children are match arms, each with its own lexical bindings; evaluation order, guards, validation, narrowing, and exhaustive coverage are the same as for an inner match. Other SFC block attributes retain their existing meaning. This does not enable other template directives on the SFC block.
+
+## Shorthand discussion (deferred)
+
+Vue already provides short forms such as [`@` for `v-on`](https://vuejs.org/api/built-in-directives.html#v-on), [`:` for `v-bind`](https://vuejs.org/api/built-in-directives.html#v-bind), and [`#` for `v-slot`](https://vuejs.org/api/built-in-directives.html#v-slot). A short form of `v-when` could make repeated arms similarly concise. The candidates below have readability drawbacks, so this RFC defers a shorthand and recommends the long form.
+
+### `?`: conditional branching
+
+`?` takes its cue from JavaScript's conditional operator, `condition ? consequent : alternate`. It suggests a branch selected by a condition and avoids spelling a JavaScript compound assignment when followed by the attribute's `=`:
+
+```html
+
+
+
+ Unknown result.
+
+```
+
+Its weakness is that `?` suggests conditional rendering generally, so it could be mistaken for a `v-if` shorthand. Its value would still be a pattern, not a truthiness test: `?="true"` would match the subject against `true`. This mnemonic is proposed for Vue; it is not shorthand defined by TC39 or Flow.
+
+### `|`: pattern-matching branches
+
+`|` has a direct precedent in [OCaml pattern matching](https://ocaml.org/docs/basic-data-types#lists) and [F# match expressions](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/match-expressions), where `| pattern -> expression` introduces an alternative branch.
+
+However, writing it as an attribute produces `|="pattern"`, which visually reads as JavaScript's bitwise OR assignment operator `|=`. Combining it with or-patterns further repeats the symbol:
+
+```html
+Waiting...
+```
+
+The attribute name and quoted pattern are unambiguous to a parser, but the compound-assignment resemblance is a readability drawback. `|` is therefore not recommended as the attribute shorthand. This does not affect `|` inside patterns, which retains its role as the or combinator.
+
+### `~` or no shorthand
+
+`~="pattern"` can suggest similarity or matching, but that is a weaker mnemonic for selecting a branch, and JavaScript uses `~` for bitwise negation. Keeping only `v-when` remains a viable choice if none of the symbols reads clearly enough.
+
+`v-match` remains the explicit name of the enclosing construct. It appears once per block, while `v-when` is repeated for every arm, so shortening the arms provides most of the benefit and keeps the subject easy to find. A second symbol for the host is not proposed.
+
+### Parsing and tooling
+
+Any selected shorthand must normalize to `v-when` before structural validation, binding analysis, and code generation. Long and short forms must produce the same directive AST apart from source locations, preserve pattern bindings and guards, and never emit the shorthand as an HTML attribute or component prop, including during SSR. Both forms require a direct `v-match` parent and can be mixed across arms.
+
+The pattern, including the `_` fallback, stays in the quoted attribute value. Neither form accepts directive arguments or modifiers; a missing pattern and combining long and short forms on the same element are compile-time errors. The guard after `if` remains a normal JavaScript expression, including its usual operators. Existing `@`, `:`, and `#` syntax keeps its meaning inside `v-match`.
+
+Editor highlighting, completion, formatting, linting, and Volar / vue-tsc would need to recognize both forms and preserve the source spelling. These candidates are not implemented by the current Vue parser. Shorthand can be deferred independently of the long form.
+
+## Branch order
+
+Branches are tested in source order. Only the first branch whose pattern and guard match is rendered.
+
+```html
+
+ Loading...
+ Something went wrong.
+ Done.
+
+```
+
+The above renders the first branch when `status` is either `'loading'` or `'pending'`, the second when it is `'error'`, and the wildcard branch otherwise.
+
+## Pattern grammar
+
+`v-when` uses a pattern grammar, not a normal JavaScript expression grammar. This is similar to how `v-for` already has directive-specific syntax.
+
+The initial pattern grammar should include the subset that is most useful in templates and that aligns with TC39 and Flow:
+
+```txt
+Pattern:
+ LiteralPattern
+ ValuePattern
+ WildcardPattern
+ BindingPattern
+ ObjectPattern
+ ArrayPattern
+ OrPattern
+ AsPattern
+ ParenthesizedPattern
+```
+
+### Literal patterns
+
+Literal patterns match primitive values:
+
+```html
+Done
+Not found
+Enabled
+No value
+```
+
+Literal matching uses JavaScript strict equality semantics, with `NaN` matched using `Number.isNaN`.
+
+### Value patterns
+
+Identifiers and member expressions can be used as value patterns:
+
+```html
+
+ Active
+ Fallback
+
+```
+
+A value pattern compares the subject to the runtime value of the expression. To keep the initial feature deterministic and friendly to tooling, arbitrary expressions are not allowed as patterns. Developers can assign an expression to a binding in `
+
+
+
+
+
+
+
+```
+
+Inside the first branch, `result` is narrowed to `{ status: 'success'; data: Article }`, and `article` is typed as `Article`. Inside the second branch, `error` is typed as `Error`. `as` bindings preserve the narrowed whole-subject type. A nested `v-match` starts from the type available within its enclosing branch.
+
+## Exhaustiveness checking
+
+Exhaustiveness is a required part of this proposal's type-tooling contract, inspired by [Flow's exhaustive checking](https://flow.org/en/docs/match/#exhaustive-checking). Every `v-match` analyzed by the template type checker must cover its subject type. A non-exhaustive match is an error by default, not an optional lint suggestion, and causes `vue-tsc --noEmit` to fail. Volar must show the corresponding diagnostic in the editor without requiring a separate ESLint rule or directive modifier.
+
+### Coverage rules
+
+The checker starts with the subject's type at the `v-match` site, after normal template ref unwrapping. It tracks the values that remain unhandled as it visits arms in source order:
+
+1. An unguarded arm removes the values its pattern is proven to match. The match is exhaustive only when no values remain.
+2. Literal and statically known singleton value patterns cover their respective values. A runtime value pattern whose type has multiple possible values cannot cover that entire type merely by comparing against its current value.
+3. An or-pattern covers the union of its alternatives. Parentheses and `as` bindings do not change the underlying pattern's coverage.
+4. Object and array patterns cover values recursively according to their runtime structure and length rules. Checking a tag only removes the entire tagged variant when its remaining subpatterns accept every value of that variant. Object rest does not narrow open-object coverage; array rest accepts all lengths at least as large as the listed prefix, provided that prefix matches. Binding a remainder does not change coverage compared with an unbound rest.
+5. An unguarded top-level `_`, `const value`, or `_ as value` covers all remaining values. A wildcard nested in a structural pattern only covers its position, subject to the enclosing shape and property-presence checks.
+6. An arm with an `if` guard removes no values from the remaining space. This also applies to `_ if (...)`, binding patterns with guards, and apparently complementary guards.
+
+The required analyzable cases include finite literal unions, booleans, enum members with statically known values, discriminated object unions, finite combinations of nested object and tuple patterns, and array length partitions with trailing rest. Coverage must account for structural subcases, rather than only removing top-level union members.
+
+`null` and `undefined` are distinct cases when present in the subject type. For example, `ref()` includes an initial `undefined` value and requires an `undefined` arm or an unconditional fallback in addition to all `Result` variants. An optional object property is not covered merely by matching its present value; the absent-property case must also be handled.
+
+An unrestricted `string` or `number`, `any`, `unknown`, or a generic type whose constraints do not establish a covered value space requires an unguarded catch-all pattern. Finite literal arms cannot exhaust an open primitive type. If the checker cannot prove coverage for a more complex type or pattern combination, it must report that limitation and request a catch-all; it must not silently mark the match exhaustive. A subject typed as `never` has no remaining values and is vacuously covered.
+
+### Missing-case diagnostics
+
+The diagnostic is attached to the `v-match` subject expression. It identifies uncovered cases and suggests valid `v-when` patterns when they can be enumerated.
+
+```vue
+
+
+
+
+
+
+
+
+
+```
+
+Adding `` completes coverage. Adding an unguarded `_` arm also completes coverage but intentionally handles future variants through the fallback. When authors want additions to a union to require a new branch, they should enumerate the variants without a catch-all.
+
+A guarded variant still needs an unguarded arm:
+
+```html
+
+
+
+
+
+
+```
+
+For a subject with success and error variants, removing the final arm must report the uncovered error variant. Neither complementary guards nor a final guarded wildcard discharge that requirement.
+
+For nested patterns, the suggested missing case should be as specific as practical. If the subject is `['left' | 'right', 'top' | 'bottom']` and three combinations are covered, the diagnostic identifies the fourth tuple pattern. A pattern `{ status: 'success', data: null }` only covers successful results with `null` data; it cannot discharge all successful results if other data values are possible.
+
+### Unreachable arms and intentional empty rendering
+
+The checker also reports a warning on an arm whose entire pattern is proven unable to match any remaining value, either because earlier unguarded arms cover it or because it is outside the subject type. A guarded arm does not make a later arm unreachable merely by matching the same structural pattern. These warnings are separate from non-exhaustive-match errors; syntactically invalid wildcard placement remains a compiler error.
+
+Intentionally rendering nothing is expressed by an empty arm, which still counts toward coverage:
+
+```html
+
+
+
+
+```
+
+The checker must analyze the arm before any optimization removes its empty render output. It must not infer that an omitted case means an intentional empty branch.
+
+### Compiler boundary
+
+The SFC compiler performs syntax and structural validation without requiring a TypeScript program. Semantic coverage diagnostics belong to Volar / vue-tsc, including JavaScript templates when the template checker has inferred types for them. Running only the template compiler or a build that does not run template type checking does not certify exhaustiveness.
+
+If no runtime arm matches because type checking was skipped or the runtime value violates its declared type, the block renders nothing. This is Vue's conditional-rendering behavior, not Flow's match-expression exception behavior. The checker must not remove that runtime path or allow an exhaustiveness result to change client or SSR branch selection.
+
+Compiler and tooling work may be developed in stages, but exhaustiveness checking with these default errors is part of the feature's acceptance criteria, not a deferred stretch goal.
+
+# Drawbacks
+
+- This adds new built-in directive syntax and a new pattern grammar.
+- The compiler has to model a parent-child relationship between `v-match` and `v-when`.
+- Pattern parsing is more complex than the previous strict-equality-only `v-case` draft.
+- Adopting a shorthand would add a symbol to learn and require coordinated parser, formatter, and editor support. Each candidate has readability trade-offs described above.
+- Required exhaustiveness errors and narrowing need coordinated Volar / vue-tsc support. Conservative analysis can require an explicit catch-all when coverage cannot be proven.
+- Users may expect this to be identical to future JavaScript pattern matching. Vue should document that it is a template-level feature with an intentionally smaller initial surface.
+
+# Alternatives
+
+## Dedicated default syntax
+
+`v-when.default` could identify a fallback separately. This RFC recommends `v-when="_"` instead: `_` is already a wildcard pattern, so it needs no separate modifier or fallback-only parsing rule. It also composes with guards and nested patterns, following Flow's wildcard spelling. Any shorthand should keep `_` in the attribute value, where every other pattern lives.
+
+## Keep the previous `v-match` / `v-case` design
+
+The earlier draft used:
+
+```html
+
+ Loading...
+ Error
+ Unknown
+
+```
+
+This is simple, but it only covers strict equality and does not scale to object patterns, branch-local bindings, or guard expressions. It also misses the TC39 `when` vocabulary.
+
+## Keep using `v-if` / `v-else-if`
+
+The current directives remain fully supported and are still best when each branch checks unrelated conditions:
+
+```html
+Admin
+Invited
+Guest
+```
+
+`v-match` is intended for branches that all inspect the same subject.
+
+## Renderless `` component
+
+```html
+
+
+
+
+
+```
+
+This can be approximated in userland, but it cannot provide compiler-level binding scopes, branch-specific type narrowing, or the same optimization opportunities.
+
+## Separate guard directive
+
+Instead of `v-when="{ ... } if (...)"`, guards could be a second directive:
+
+```html
+
+```
+
+This is easier to parse but weaker as a pattern-matching story. Flow places guards on the arm, and TC39 models guards as part of the pattern. Keeping the guard inside `v-when` makes the branch read as one unit.
+
+## Adopt all Flow patterns immediately
+
+Flow includes instance patterns such as:
+
+```js
+match (shape) {
+ Circle { const radius, ... } => radius,
+ Square { const side, ... } => side,
+}
+```
+
+Vue could eventually support class / component instance patterns, but they are not required for the initial template feature. Object, array, wildcard, binding, `|`, `as`, and guard patterns cover the common UI state cases with less runtime and parser complexity.
+
+# Adoption strategy
+
+- Existing `v-if` / `v-else-if` / `v-else` code continues to work. Any shorthand would reserve new attribute syntax; compatibility with existing literal attributes must be reviewed before adopting a symbol.
+- Documentation should introduce `v-match` beside conditional rendering, emphasizing one-subject branching and branch-local bindings.
+- Documentation should teach `v-when` first, then any adopted shorthand with the same semantics. Formatters and codemods should not force either spelling.
+- ESLint rules can suggest `v-match` when a `v-if` chain repeatedly checks the same subject.
+- A codemod can convert simple strict-equality chains to `v-match` / `v-when`.
+- Implementation can proceed incrementally, but the completed feature must include the specified exhaustiveness errors, narrowing, and unreachable-arm warnings in Volar / vue-tsc.
+
+# Unresolved questions
+
+1. Should future rest patterns allow a nested pattern after `...`, beyond the initial unbound rest and `...const identifier` forms?
+2. Should `let` bindings ever be supported in templates, or should Vue intentionally keep branch bindings immutable with `const` only?
+3. Should Vue expose a public compiler AST node for pattern syntax so Volar, eslint-plugin-vue, and custom tooling can share the parser?
+4. How should the pattern coverage analysis be shared between Volar / vue-tsc and optional lint rules while preserving the required error semantics?
+5. Should runtime object pattern matching use `in` semantics, own-property semantics, or align exactly with the eventual ECMAScript proposal?
+6. Should custom matcher protocols be considered later if TC39's `Symbol.customMatcher` advances?
+7. Is there a shorthand that reads clearly as a match arm in attribute syntax? The current proposal keeps `v-when` long-form and defers symbol selection.