vroqjs.com

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.