Rosetta Stone
Live Demos HubRosetta Stone
Interactive production-grade hypermedia component for HTMXUI.
Interactive Preview
React & Vue → HTMXUI Rosetta Stone
Direct side-by-side translation guide mapping familiar React and Vue concepts to native HTMXUI declarative patterns.
1. State & Reactivity
| React | Vue 3 | HTMXUI |
|---|---|---|
| const [count, setCount] = useState(0) | const count = ref(0) | <script type="application/json" hx-state> {"count": 0} </script> |
| const total = useMemo(() => price * qty, [price, qty]) | const total = computed(() => price.value * qty.value) | hx-computed='{ "total": price * qty }' |
| useEffect(() => { log(count) }, [count]) | watchEffect(() => { log(count.value) }) | hx-effect="console.log(count)" |
| useContext(AuthContext) | inject('auth') / Pinia store | $store.auth.user |
2. Template Directives & DOM Control
| React | Vue 3 | HTMXUI |
|---|---|---|
| <span>{user.name}</span> | <span>{{ user.name }}</span> | <span hx-text="user.name"></span> |
| {items.map(item => <Item key={item.id} />)} | <div v-for="item in items" :key="item.id"> | <template hx-for="item in items"><div>...</div></template> |
| {isLoggedIn && <Dashboard />} | <div v-if="isLoggedIn"> | <template hx-if="isLoggedIn"><div>...</div></template> |
| <div style={{ display: open ? 'block' : 'none' }}> | <div v-show="open"> | <div hx-show="open" hx-transition="fade"> |
| value={val} onChange={e => setVal(e.target.value)} | v-model="val" | hx-model="val" (or hx-model.number, hx-model.lazy) |
| onClick={(e) => { e.preventDefault(); submit(); }} | @click.prevent="submit" | hx-on:click.prevent="submit()" or @click.prevent="submit()" |
HTML Source
<div class="space-y-10 max-w-4xl py-6">
<!-- Title & Subtitle -->
<div class="space-y-3">
<h1 class="text-4xl font-extrabold tracking-tight text-foreground">React & Vue → HTMXUI Rosetta Stone</h1>
<p class="text-lg text-muted-foreground leading-relaxed font-medium">
Direct side-by-side translation guide mapping familiar React and Vue concepts to native HTMXUI declarative patterns.
</p>
</div>
<!-- Table 1: State & Reactivity -->
<div class="space-y-4">
<h2 class="text-2xl font-bold tracking-tight text-foreground border-b border-border pb-2">1. State & Reactivity</h2>
<div class="overflow-x-auto rounded-xl border border-border bg-card shadow-sm">
<table class="w-full text-left text-xs border-collapse">
<thead class="bg-muted/50 border-b border-border text-foreground font-semibold">
<tr>
<th class="py-3 px-4 w-1/4">React</th>
<th class="py-3 px-4 w-1/4">Vue 3</th>
<th class="py-3 px-4 w-1/2">HTMXUI</th>
</tr>
</thead>
<tbody class="divide-y divide-border text-muted-foreground font-mono">
<tr class="hover:bg-muted/30">
<td class="py-3 px-4 text-sky-500">const [count, setCount] = useState(0)</td>
<td class="py-3 px-4 text-emerald-500">const count = ref(0)</td>
<td class="py-3 px-4 text-primary font-bold"><script type="application/json" hx-state><br>{"count": 0}<br></script></td>
</tr>
<tr class="hover:bg-muted/30">
<td class="py-3 px-4 text-sky-500">const total = useMemo(() => price * qty, [price, qty])</td>
<td class="py-3 px-4 text-emerald-500">const total = computed(() => price.value * qty.value)</td>
<td class="py-3 px-4 text-primary font-bold">hx-computed='{ "total": price * qty }'</td>
</tr>
<tr class="hover:bg-muted/30">
<td class="py-3 px-4 text-sky-500">useEffect(() => { log(count) }, [count])</td>
<td class="py-3 px-4 text-emerald-500">watchEffect(() => { log(count.value) })</td>
<td class="py-3 px-4 text-primary font-bold">hx-effect="console.log(count)"</td>
</tr>
<tr class="hover:bg-muted/30">
<td class="py-3 px-4 text-sky-500">useContext(AuthContext)</td>
<td class="py-3 px-4 text-emerald-500">inject('auth') / Pinia store</td>
<td class="py-3 px-4 text-primary font-bold">$store.auth.user</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- Table 2: Templating & Directives -->
<div class="space-y-4">
<h2 class="text-2xl font-bold tracking-tight text-foreground border-b border-border pb-2">2. Template Directives & DOM Control</h2>
<div class="overflow-x-auto rounded-xl border border-border bg-card shadow-sm">
<table class="w-full text-left text-xs border-collapse">
<thead class="bg-muted/50 border-b border-border text-foreground font-semibold">
<tr>
<th class="py-3 px-4 w-1/4">React</th>
<th class="py-3 px-4 w-1/4">Vue 3</th>
<th class="py-3 px-4 w-1/2">HTMXUI</th>
</tr>
</thead>
<tbody class="divide-y divide-border text-muted-foreground font-mono">
<tr class="hover:bg-muted/30">
<td class="py-3 px-4 text-sky-500"><span>{user.name}</span></td>
<td class="py-3 px-4 text-emerald-500"><span>{{ user.name }}</span></td>
<td class="py-3 px-4 text-primary font-bold"><span hx-text="user.name"></span></td>
</tr>
<tr class="hover:bg-muted/30">
<td class="py-3 px-4 text-sky-500">{items.map(item => <Item key={item.id} />)}</td>
<td class="py-3 px-4 text-emerald-500"><div v-for="item in items" :key="item.id"></td>
<td class="py-3 px-4 text-primary font-bold"><template hx-for="item in items"><div>...</div></template></td>
</tr>
<tr class="hover:bg-muted/30">
<td class="py-3 px-4 text-sky-500">{isLoggedIn && <Dashboard />}</td>
<td class="py-3 px-4 text-emerald-500"><div v-if="isLoggedIn"></td>
<td class="py-3 px-4 text-primary font-bold"><template hx-if="isLoggedIn"><div>...</div></template></td>
</tr>
<tr class="hover:bg-muted/30">
<td class="py-3 px-4 text-sky-500"><div style={{ display: open ? 'block' : 'none' }}></td>
<td class="py-3 px-4 text-emerald-500"><div v-show="open"></td>
<td class="py-3 px-4 text-primary font-bold"><div hx-show="open" hx-transition="fade"></td>
</tr>
<tr class="hover:bg-muted/30">
<td class="py-3 px-4 text-sky-500">value={val} onChange={e => setVal(e.target.value)}</td>
<td class="py-3 px-4 text-emerald-500">v-model="val"</td>
<td class="py-3 px-4 text-primary font-bold">hx-model="val" (or hx-model.number, hx-model.lazy)</td>
</tr>
<tr class="hover:bg-muted/30">
<td class="py-3 px-4 text-sky-500">onClick={(e) => { e.preventDefault(); submit(); }}</td>
<td class="py-3 px-4 text-emerald-500">@click.prevent="submit"</td>
<td class="py-3 px-4 text-primary font-bold">hx-on:click.prevent="submit()" or @click.prevent="submit()"</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>