TSX in. Your stack out.
Barefoot compiles signal-based TSX into Hono, Echo, or whatever stack you ship on.
No virtual DOM. No SPA required.
Counter.tsx
SOURCE"use client"
import { createSignal } from '@barefootjs/client'
export function Counter() {
const [count, setCount] = createSignal(0)
return (
<button onClick={() => setCount(c => c + 1)}>
Count: {count()}
</button>
)
}// Hydrate your template
import { createSignal, createEffect, find, hydrate } from '@barefootjs/client'
export function initCounter(__scope, props = {}) {
const [count, setCount] = createSignal(props.count ?? 0)
const _slot_0 = find(__scope, '[bf="slot_0"]')
const _slot_1 = find(__scope, '[bf="slot_1"]')
createEffect(() => {
if (_slot_0) _slot_0.textContent = String(count())
})
if (_slot_1) _slot_1.onclick = () => setCount(c => c + 1)
}
hydrate('Counter', { init: initCounter })
// Hono JSX Template
export function Counter({ count = 0 }) {
return (
<button bf-s="Counter" bf="slot_1">
Count: <span bf="slot_0">{count}</span>
</button>
)
}
{{/* Go html/template */}}
<button bf-s="Counter" bf="slot_1">
Count: <span bf="slot_0">{{ .Count }}</span>
</button>
% # Mojolicious template
<button bf-s="Counter" bf="slot_1">
Count: <span bf="slot_0"><%= $count %></span>
</button>
<!-- Rendered & hydrated in the browser -->
<button bf-s="Counter" bf="slot_1">
Count: <span bf="slot_0">0</span>
</button>
01
Backend Freedom
Hono, Echo, Mojolicious... your favorite template
02
MPA-style
Add to existing apps
03
Fine-grained
Signal-based reactivity
04
AI-native
CLI + fast IR tests
One more thing...
Ready-made UI Components
Pick a component. Copy the code. Make it yours.
Explore UI Components →