Frameworks
fs-* attributes are plain HTML — they work in any framework that renders to the DOM. In practice each framework has a few binding-specific patterns and one or two framework-native traps worth documenting. Start with your stack's page.
Pages
| Framework | Category | Notes |
|---|---|---|
| React | CSR SPA | JSX binding, TypeScript augmentation, the boolean attribute trap |
| Vue | CSR SPA | inheritAttrs, template binding, dynamic expressions |
| Svelte | CSR SPA | Attribute pass-through, reactive values |
| Solid | CSR SPA | Signals, reactive attribute expressions |
| Alpine | Directive-only | Works directly in server-rendered HTML with no build step |
| HTMX | Server-rendered + swap | Swap-strategy affects type choice, OOB swaps, HX-Trigger header for async events |
| Hotwire | Turbo + Stimulus | Turbo Streams, morphing, Frames |
| Livewire | Laravel + morph | Morphdom patches, wire:model |
| LiveView | Phoenix + morph | LiveView morphing, phx bindings |
| Astro | SSR + islands | Static HTML + hydration islands |
What's the same everywhere
fs-*are plain string attributes- The assertion key convention (
feature/action) is framework-agnostic - All triggers, assertions, and modifiers work identically
- The patterns cookbook covers common scenarios without framework-specific glue
What varies by framework
- Binding syntax for dynamic values. Template literals in React JSX,
:attrin Vue,{expression}in Svelte, EJS/ERB/HEEx interpolation in server templates. See Dynamic assertion values in the cookbook. - Attribute pass-through on custom components. Native elements pass
fs-*through automatically. Custom components must forward props to the root DOM element. - Boolean attribute gotchas. React drops bare boolean attributes — always use explicit string values (
fs-assert-mutex="each", notfs-assert-mutex). - Swap-strategy correctness. Frameworks that do server-rendered partial swaps (HTMX, Hotwire, Livewire, LiveView) force the
addedvsupdatedchoice on the swap strategy, not on what the markup looks like. The HTMX page has the full swap table. - Morphing vs replacement. Frameworks that use morphdom-style patching (Livewire, LiveView, Turbo 8 morphing) preserve element identity — content mutates in place, so use
updated. Frameworks that replace elements (HTMXhx-swap="outerHTML"without morph) remove and re-insert — useadded.
Supported matrix
Every framework above is covered by the conformance suite: a real framework harness exercising the same set of scenarios against a Chromium browser.