--- name: refui description: "Use when working with rEFui (refui) applications where you cannot rely on reading the library source. Covers the retained-mode + signals mental model, DOM/HTML/Reflow renderers, JSX setup (classic pragma vs automatic runtime), directives (on:/class:/style:/attr:/prop:/m: macros), HMR via refurbish/refui/hmr, debugging “UI not updating” issues, and migrating React/Vue/Solid/Svelte patterns to rEFui." --- # rEFui ## Overview Apply rEFui’s retained-mode + signals model correctly, choose the right JSX mode/renderer, and fix reactivity/lifecycle issues without importing patterns from other UI frameworks. ## General guide ### Mental model (retained mode) - Component bodies are **setup**: they run once; they do not “re-render”. - JSX is evaluated once; **signals** update the already-built UI incrementally. - If something “doesn’t update”, you almost always read `.value` too early (non-reactively) or mutated in place without `trigger()`. ### Signals & reactivity - State: `const count = signal(0)` - Reactive JSX: `{count}` (not `{count.value}`) - Derived: `const label = $(() => `Count: ${count.value}`)` and then `{label}` - In-place mutation: call `sig.trigger()` after mutating arrays/objects. ```jsx import { signal, $ } from 'refui' const Counter = () => { const count = signal(0) return ( ) } ``` ### Effects & cleanup - Reactive effect: `watch(() => { ...reads signals... })` - Setup/cleanup: `useEffect(() => { ...; return () => cleanup })` - Teardown-only: `onDispose(() => cleanup)` - Scheduling: if you need “after updates applied”, `await nextTick()`. ### Control flow components - Conditional UI: `{() => }{() => }` - Lists: `{({ item, index }) => ...}` - Inline dynamic subtree with lifecycle: `{(ctx) => ...}` - `For` has **no** `fallback`; for empty states, wrap with ``. ```jsx import { signal, $, If, For } from 'refui' const App = () => { const items = signal([{ id: 1, name: 'A' }]) return ( items.value.length)}> {() => {({ item }) =>
{item.name}
}
} {() =>
Empty
}
) } ``` ### Async UI - `` for a single promise boundary. - `` to group multiple async subtrees under one fallback. - `lazy(() => import(...))` for code-splitting; pair with fallback boundaries. See `references/async-suspense-transition.md` for the “rules of engagement”. ### Context Use context for shared subtree values. If consumers must react to changes, provide a signal as the context value. ```jsx import { signal, $, createContext, useContext } from 'refui' const Theme = createContext(signal('light'), 'Theme') const Button = () => { const theme = useContext(Theme) return } ``` Non-Reflow/custom renderer: wrap Provider children in a function so they inherit context: `{() =>