Getting started

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.

bash
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

vite.config.ts
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

tsconfig.json
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "@velozjs/dom",
    "moduleResolution": "bundler",
    "strict": true
  }
}

Your first component

index.html
<div id="app"></div>
<script type="module" src="/src/main.tsx"></script>
src/main.tsx
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.