Getting started
Install Veloz, add the Vite plugin and render your first component.
Install
You need Node 20+, Vite 5 or newer (Vite 8 works) and, for TypeScript, version 5.1 or newer.
npm install @velozjs/dom
npm install -D vite vite-plugin-veloz typescript@velozjs/dom includes the reactive core (@velozjs/core) and re-exports it, so one import is enough for most apps. Add @velozjs/css for scoped styles and @velozjs/ssr when you render on the server.
Configure Vite
import { defineConfig } from 'vite';
import veloz from 'vite-plugin-veloz';
export default defineConfig({
plugins: [veloz()],
});The plugin sets up JSX for Veloz and, during server rendering, points your imports of @velozjs/dom at @velozjs/ssr.
Configure TypeScript
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@velozjs/dom",
"moduleResolution": "bundler",
"strict": true
}
}Your first component
<div id="app"></div>
<script type="module" src="/src/main.tsx"></script>import { render, createSignal, createMemo, Show } from '@velozjs/dom';
function Counter() {
const [count, setCount] = createSignal(0);
const doubled = createMemo(() => count() * 2);
return (
<main>
<p>Count: {count} · doubled: {doubled}</p>
<button onClick={() => setCount((c) => c + 1)}>Add one</button>
<Show when={() => count() >= 10}>
<p>That's a lot of clicks.</p>
</Show>
</main>
);
}
render(() => <Counter />, document.getElementById('app')!);Run npx vite and open the page. Clicking the button updates two text nodes and nothing else: Counter itself never runs again.
{count}works because a getter is a function. Any function in JSX becomes a live region that updates when the signals it reads change.
What to read next
- Reactivity: signals, memos, effects and how updates are scheduled.
- Components and JSX: the mental model in three rules.
- Server rendering: render to HTML and hydrate on the client.