Quick Start
Build a working Whisq app in under 5 minutes.
1. Create a Project
Section titled “1. Create a Project”npm create whisq@latest my-appcd my-appnpm installnpm run devOpen http://localhost:5173 — you should see a counter app.
2. Understand the Code
Section titled “2. Understand the Code”Open src/main.ts:
import { signal, component, div, h1, button, span, mount } from "@whisq/core";
const Counter = component((props: { initial?: number }) => { const count = signal(props.initial ?? 0);
return div({ class: "counter" }, h1("Whisq Counter"), button({ onclick: () => count.value-- }, "-"), span({ class: "count" }, () => ` ${count.value} `), button({ onclick: () => count.value++ }, "+"), );});
const App = component(() => { return div({ class: "app" }, Counter({ initial: 0 }), );});
mount(App({}), document.getElementById("app")!);Let’s break this down:
Signals — reactive state
Section titled “Signals — reactive state”const count = signal(0); // create a reactive valuecount.value++; // write — triggers updates everywhereElements — typed HTML functions
Section titled “Elements — typed HTML functions”div({ class: "counter" }, // props object (optional) h1("Whisq Counter"), // text child button({ onclick: fn }), // event handler span(() => count.value), // reactive child (function))Every HTML tag is a function: div(), span(), button(), input(), h1(), etc.
Components — setup functions
Section titled “Components — setup functions”const Counter = component((props) => { // setup code runs once const count = signal(0);
// return a WhisqNode return div(/* ... */);});
// use it — it's a function callCounter({ initial: 10 })3. Make a Change
Section titled “3. Make a Change”Try editing src/main.ts:
// Change the titleh1("My First Whisq App"),
// Add a computed displayconst doubled = computed(() => count.value * 2);
// Show itp(() => `Doubled: ${doubled.value}`),Don’t forget to import computed and p:
import { signal, computed, component, div, h1, p, button, span, mount } from "@whisq/core";Save — Vite hot-reloads instantly.
4. Key Rules
Section titled “4. Key Rules”Rule 1: Wrap reactive values in functions
// ❌ WRONG — static, never updatesspan(count.value)
// ✅ RIGHT — reactive, updates automaticallyspan(() => count.value)Rule 2: Don’t mutate arrays in-place
// ❌ WRONG — won't trigger updatesitems.value.push(newItem)
// ✅ RIGHT — creates new array, triggers updatesitems.value = [...items.value, newItem]Rule 3: Events are on* props with functions
// ❌ WRONG — string handlerbutton({ onclick: "doSomething()" })
// ✅ RIGHT — function handlerbutton({ onclick: () => doSomething() })Next Steps
Section titled “Next Steps”- Installation — All the ways to add Whisq to a project
- Your First Component — Build a real component step by step
- Signals — Deep dive into reactive state