--- title: Components sort: 110 section-id: core-concepts keywords: components, props, slots, lifecycle, tsx, velox components, islands description: The Velox component model, including props, slots, lifecycle hooks, and the islands architecture language: en --- # Components Velox components are TypeScript/TSX files that describe a piece of UI. They are the fundamental building blocks of a Velox application — reusable, composable, and by default rendered entirely on the server. ## Defining a Component A basic Velox component is a TypeScript function that returns JSX: ```tsx // components/Greeting.tsx interface GreetingProps { name: string; formal?: boolean; } export default function Greeting({ name, formal = false }: GreetingProps) { const salutation = formal ? 'Good day' : 'Hello'; return

{salutation}, {name}!

; } ``` Use it in a route or another component: ```tsx --- import Greeting from '../components/Greeting.tsx'; ---
``` ## Props Props are typed using TypeScript interfaces or types. All props are validated at compile time — no runtime prop checking overhead. ```tsx interface CardProps { title: string; description: string; href?: string; variant?: 'default' | 'featured' | 'compact'; children?: VeloxNode; } export default function Card({ title, description, href, variant = 'default', children, }: CardProps) { return (

{href ? {title} : title}

{description}

{children &&
{children}
}
); } ``` ### Default Props Set default values directly in the destructuring parameter, as shown above. Velox does not use a separate `defaultProps` mechanism. ### Required vs Optional Props By TypeScript convention, optional props are marked with `?`. Omitting a required prop is a compile-time error. ## Slots The `children` prop is the default slot — content placed between the opening and closing tags of a component: ```tsx

This is the card body.

``` ### Named Slots For more complex component APIs, use named slot props: ```tsx interface ModalProps { title: VeloxNode; footer?: VeloxNode; children: VeloxNode; } export default function Modal({ title, footer, children }: ModalProps) { return ( ); } ``` Usage: ```tsx Confirm Delete} footer={ <> } >

Are you sure you want to delete this item?

``` ## Server vs Client Components By default, all Velox components run on the server. They have no JavaScript bundle size on the client and cannot use browser APIs or client-side reactivity. To make a component interactive on the client, use the `client:*` hydration directive when you include it in a route: ```tsx --- import Counter from '../components/Counter.tsx'; import LazyChart from '../components/LazyChart.tsx'; --- ``` ### Writing Client Components Client components can use signals, effects, and browser APIs: ```tsx import { signal, effect, onMount, onCleanup } from 'velox/client'; export default function LiveClock() { const time = signal(new Date().toLocaleTimeString()); onMount(() => { const interval = setInterval(() => { time.value = new Date().toLocaleTimeString(); }, 1000); onCleanup(() => clearInterval(interval)); }); return

Current time: {time}

; } ``` ## Lifecycle Hooks Client-side components can use the following lifecycle hooks: | Hook | When it runs | |------|-------------| | `onMount(fn)` | After the component is first rendered and inserted into the DOM | | `onUpdate(fn)` | After every re-render (reactive signal change) | | `onCleanup(fn)` | Before the component unmounts or before the next `onUpdate` call | | `onDestroy(fn)` | When the component is permanently unmounted | ```tsx import { signal, onMount, onUpdate, onCleanup } from 'velox/client'; export default function DataComponent() { const data = signal([]); const loading = signal(true); onMount(async () => { const response = await fetch('/api/data'); data.value = await response.json(); loading.value = false; }); onCleanup(() => { // abort pending requests, clear timers, etc. }); return (
{loading.value ?

Loading...

:
    {data.value.map(d =>
  • {d.name}
  • )}
}
); } ``` ## Component Composition Patterns ### Higher-Order Components ```tsx function withAuth(Component: VeloxComponent) { return function AuthGated(props: T) { const user = useUser(); if (!user) return ; return ; }; } ``` ### Render Props / Function-as-Children ```tsx interface FetcherProps { url: string; render: (data: T) => VeloxNode; } export function Fetcher({ url, render }: FetcherProps) { // ... fetch logic return render(data); } ``` ## Component Library Velox ships an optional official component library `@velox/ui` with accessible, unstyled base components. Install it separately: ```bash npm install @velox/ui ``` ```tsx import { Button, Input, Dialog } from '@velox/ui'; ``` See the [Component API](api-components.md) reference for the full `defineComponent` API and advanced component patterns.