99-reference/file-templates.md
File templates
File templates
This file provides compact starter templates for common Vroq files.
Use these templates as a baseline and then adapt them to the owning feature.
app.json
{
"version": 1,
"vroqjs": "v01",
"release": false
}
If the prompt does not specify the framework version, default to v01.
index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>App</title>
<link rel="stylesheet" href="/vroqjs/{{app.vroqjs}}/ui.css" />
<script>
window.__VROQ_RELEASE__ = {{app.release}};
</script>
<script type="importmap">
{
"imports": {
"/vroqjs/": "/ignore--{{app.time}}/vroqjs/{{app.vroqjs}}/",
"@app/": "./ignore--{{app.time}}/",
"codemirror": "https://esm.sh/codemirror?target=es2022",
"@codemirror/state": "https://esm.sh/@codemirror/state?target=es2022",
"@codemirror/view": "https://esm.sh/@codemirror/view?target=es2022",
"@codemirror/commands": "https://esm.sh/@codemirror/commands?target=es2022",
"@codemirror/lang-javascript": "https://esm.sh/@codemirror/lang-javascript@6?target=es2022"
}
}
</script>
</head>
<body>
<div id="app"></div>
<script type="module" src="/ignore--{{app.time}}/App.js?v={{app.time}}"></script>
</body>
</html>
App.js
import { mount, $state } from "/vroqjs/runtime.js";
import { VStack, Text, Button } from "/vroqjs/ui.js";
import { configureStore } from "./shared/store/configureStore.js";
function App() {
const store = $state(() => configureStore())();
const state = store.state();
return VStack(
{ gap: "md", style: { padding: "32px" } },
Text("Hello VroqJS", { as: "div", size: "h1" })
);
}
## Local component state pattern
When using `$state` for **local component state**, always initialize it with a function and immediately call it:
const count = $state(() => 0)();
Do **not** write:
const count = $state(0);
The `$state` helper expects a factory function. Using the direct value form can break reactivity or cause runtime errors.
mount(document.getElementById("app"), App);
Use /vroqjs/ui.js as the preferred UI import surface for common components. If you need a specific component file, list the framework files first and then use an explicit import from /vroqjs/components/*.js.
Critical signature reminder
Do not guess helper signatures.
For Text(...), the first argument is the text content and props come after it:
Text("Hello")
Text("Hello", { as: "div", size: "h1" })
Text(String(value), { weight: 700 })
Do not write:
Text({ as: "h1" }, "Hello")
That produces broken output like [object Object]Hello.
configureStore.js
import { createStore } from "/vroqjs/system/store/createStore.js";
import { initialState } from "./initialState.js";
import { featureReducer } from "../../features/feature/index.js";
export function configureStore() {
return createStore([
featureReducer
], initialState);
}
initialState.js
export const initialState = {
feature: {}
};
featureActions.js
import { action } from "/vroqjs/system/store/action.js";
const _setThing = action("FEATURE_SET_THING", {
description: "Set the feature value.",
payload: {
value: {
type: "string",
required: true,
description: "The new feature value."
}
},
examples: [{ value: "hello" }]
});
export const setThing = (value) => _setThing({ value });
featureReducer.js
export function featureReducer(state, action) {
const s = state || {};
switch (action?.type) {
case "FEATURE_SET_THING":
return {
...s,
value: action.payload.value
};
default:
return state;
}
}
apiClient.js
import { btRun } from "../debugger/btClient.js";
export async function loadThing() {
const res = await btRun("thing_load", {});
if (!res?.ok) throw new Error(res?.error || "thing_load failed");
return res.result;
}
Final rule
Use templates as a starting point, but always adapt names, state shape, and ownership to the real feature.