Skip to main content
Vertz has strong conventions. None of these are enforced by the compiler or runtime — they’re patterns that keep your code consistent, readable, and predictable for both humans and LLMs.

Component signatures

Destructure props in the parameter

Props interface naming

Name the interface ComponentNameProps. Use the on prefix for callback props.

Don’t annotate return types

Let TypeScript infer component return types. The JSX factory maps tag names to specific element types — an explicit : HTMLElement annotation is a lossy upcast.

Reactivity

let for local state

Use let for local state. The compiler transforms it into a signal automatically.

const for derived values

Use const for values derived from state. The compiler wraps it in computed() automatically.

JSX

Fully declarative

All UI code must be declarative. No appendChild, innerHTML, textContent assignment, setAttribute, or document.createElement.
If you can’t express something declaratively, that’s a framework gap — not a reason to use imperative DOM APIs.

Use JSX for components, not function calls

Conditionals with && and ternary

Lists with .map() and key

Styling

css() for scoped styles

variants() for parameterized styles

Inline style only for dynamic values

Use css() tokens for anything theme-related. Reserve inline styles for one-off layout values like margins, transforms, or dynamic positioning.

Data fetching

query() is auto-disposed

Don’t manually manage query lifecycle — queries auto-register cleanup with the component scope. When the component unmounts, the query stops reactive effects and timers automatically.

Access query properties directly

Query properties like .data, .loading, and .error work directly in both JSX and event handlers — no unwrapping needed.

Context

Create a convenience hook

Always create a typed use* accessor that throws on missing provider.

Router

Pages use useRouter(), not props

Pages access the router via context — no prop threading.