Your first page
A Reactra page is a component block. The scaffold’s home page is a counter — let’s
read it line by line. It lives at src/pages/index.tsx:
import styles from "./index.module.css"
export component HomePage { meta { title: "My App" }
state count: number = 0 derived label = count === 1 ? "1 click" : `${count} clicks` action inc() { count = count + 1 }
view { <main className={styles.app}> <h1>Welcome to Reactra</h1> <p>{label}</p> <button type="button" onClick={inc}>click me</button> </main> }}import styles from "./index.module.css"import { useCallback, useEffect, useMemo, useState } from "react"
export const HomePage = () => { const [count, setCount] = useState((0) as number) const label = useMemo(() => count === 1 ? "1 click" : `${count} clicks`, [count]) const inc = useCallback(() => { setCount(prev => prev + 1) }, []) const __meta = { title: "My App" } useEffect(() => { if (typeof document !== "undefined" && __meta.title != null) document.title = String(__meta.title) }, [__meta.title]) useEffect(() => { const h = globalThis.__REACTRA_TEST__; if (h) h.update("HomePage", { count, label, inc }) }) return (<> <main className={styles.app}> <h1>Welcome to Reactra</h1> <p>{label}</p> <button type="button" onClick={inc}>click me</button> </main> </>)}export default HomePageThe four keywords
Section titled “The four keywords”statedeclares reactive local state.state count: number = 0compiles to auseState. Writingcount = count + 1(inside anaction) is a real assignment in the DSL — the compiler turns it into the setter call.derivedis computed state.labelrecomputes whenevercountchanges; you never call it, you read it. It compiles to a plain expression (nouseMemounless it pays for itself).actionis an event handler / mutation.inc()is wired toonClickin the view. Inside an action, assignments tostateare reactive writes.viewis the JSX the component renders. It’s ordinary React JSX with the component’sstate/derived/actionnames in scope.
meta { title: "My App" } sets the document title for this route. It accepts a
template string, so it can interpolate state: meta { title: \${count} clicks` }`.
File-based routing
Section titled “File-based routing”The file’s path is its route. src/pages/index.tsx → /. Drop a new file at
src/pages/about.tsx and it’s automatically routed to /about — no route config to
edit. Dynamic segments use brackets: src/pages/users/[id].tsx → /users/:id, and
id is available as a param.
See Project structure for the full layout, and the Guide for the rest of the component surface.