#What is BarefootJS?
BarefootJS is a compiler. It takes a JSX component and splits it into a marked template for your server and a client script for the browser.
"use client"
import { createSignal } from '@barefootjs/client'
export function Counter() {
const [count, setCount] = createSignal(0)
return (
<button onClick={() => setCount(n => n + 1)}>
Count: {count()}
</button>
)
}The marked template renders the HTML with bf-* attributes that tell the client script where to attach:
export function Counter({ __instanceId, ... }) {
const __scopeId = __instanceId || `Counter_${Math.random().toString(36).slice(2, 8)}`
const count = () => 0
return (
<button bf-s={__scopeId} bf="s1">
Count: {bfText("s0")}{count()}{bfTextEnd()}
</button>
)
}{{define "Counter"}}
<button bf-s="{{bfScopeAttr .}}" bf="s1">
Count: {{bfTextStart "s0"}}{{.Count}}{{bfTextEnd}}
</button>
{{end}}The client script creates the signal, wires an effect to the s0 text slot, and binds the click handler to s1 — How It Works shows the generated code.
#Why BarefootJS
- Backend freedom. The compiler emits native templates for Hono, Go, Perl, Ruby, Python, PHP, Rust and Java, so no Node.js runs at serving time. Adapters lists every backend.
- MPA-style. Components are server-rendered by default;
"use client"opts a component into shipping JavaScript. Your routing, data fetching and deployment stay as they are. - Fine-grained reactivity. Components run once. The compiler connects each signal to the DOM nodes that read it, and an update touches only those nodes — no virtual DOM, no re-render. See Reactivity.
Only the components you mark ship JavaScript:
// ProductPage.tsx — server component
import { AddToCart } from './AddToCart' // "use client"
import { ReviewStars } from './ReviewStars' // "use client"
export function ProductPage({ product }) {
return (
<div>
<h1>{product.name}</h1>
<p>{product.description}</p>
<img src={product.image} />
<ReviewStars rating={product.rating} />
<AddToCart productId={product.id} />
</div>
)
}h1, p and img produce zero JS. ReviewStars and AddToCart become interactive after hydration; the HTML is visible before that.
Continue with the Quick Start to scaffold an app, or How It Works for compilation and hydration in detail.