Signals counter (island)

Server renders the counter to HTML with resumability markers. The signals hydration runtime walks the markers, binds each {count.value} to its DOM text node, and reactively updates on click — no virtual DOM, no re-render of the surrounding markup.

Tip
Signals update only the exact text node bound to the value — not the whole component. Unlike a "use client" island, sibling elements stay untouched. Pass multiple signal values to one component: each updates independently.

Output



count: 7 (×2 = 14)

src/components/Counter.tsxTSX
"use signals";
/** @jsxImportSource @bext-stack/framework/signals */
import { signal, computed } from "@bext-stack/framework/signals";

export default function Counter(props: { initial?: number }) {
    const count = signal(props.initial ?? 0);
    const doubled = computed(() => count.value * 2);
    return (
        <div>
            <p>count: {count.value} (×2 = {doubled.value})</p>
            <button onClick={() => { count.value++; }}>+1</button>
            <button onClick={() => { count.value--; }}>−1</button>
        </div>
    );
}
src/app/examples/signals-counter/page.tsxTSX
import { signalsIsland } from "@bext-stack/framework/signals";
import Counter from "../../../components/Counter";

export default function Page() {
    return signalsIsland("Counter", Counter, { initial: 7 });
}