⬡ FRAMEWERK
Guides

Code generation

One Framewerk screen and the React it lowers to — routes, components, state and actions mapped field by field.

View as Markdown

Code generation

A Framewerk document carries enough structure to generate code from: route for the URL, instructions for what the path cannot say, components for reusable subtrees, and action strings for navigation. This guide shows one screen and the React it lowers to, then the mapping table.

Nothing here runs a generator for you — it is the contract a generator (or an agent) follows.

One screen

A sign-in screen
phone
SPEC.JSON
RENDERED OUTPUTFRAMEWERK RENDERER
Sign in
you@example.com
Continue
Edit the JSON to update the rendered screen.Edits stay in this preview

The React it lowers to

// app/signin/page.tsx  — route "/signin" from screen.signin
"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";

export default function SigninPage() {
  const router = useRouter();
  const [email, setEmail] = useState(""); // stateVars.email

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 16, padding: 24 }}>
      <h1>Sign in</h1> {/* text[variant=heading] */}
      <label>
        Email
        <input
          placeholder="you@example.com"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
        />
      </label>
      <button onClick={() => router.push("/")}>Continue</button>
      {/* action: navigate(home) → route "/" from screen.home */}
    </div>
  );
}

route picks the file. instructions become comments or JSDoc above the component. stateVars become useState seeds (always strings in the spec; coerce in the component). Action strings become the router call.

Mapping table

FramewerkReact (Next App Router)
screens[].idRoute segment / component name
screens[].routeFile path under app/ (/signin → app/signin/page.tsx)
screens[].instructionsFile-level comment or JSDoc
stateVarsuseState per variable (string initial)
type: "column" / "row"flexDirection: "column" / "row" on a div
type: "text"<p> or <span>; variant: "heading" → <h1>–<h3>
type: "button"<button>
type: "input"<input> (+ <label> when label is set)
type: "image"<img>
action: "navigate(id)"router.push(screen[id].route)
action: "back()"router.back()
action: "setState(k, v)" / toggleState(k)setState / updater on the matching useState
action: "scrollTo(anchor)"scrollIntoView() on the element the anchor names
action: "openUrl(address)"<a href target="_blank" rel="noopener noreferrer">, or window.open on a control that is not a link
components{}A React component per key; props → typed props
slotsChildren / render-prop slots on the component
styles[].tokensCSS custom properties on a root wrapper
showWhen / hideWhenConditional render ({cond && <…/>})
flows[]Documentation only — navigation comes from action

React Native maps the same way: column/row are already flex defaults, button → Pressable, navigate → the router your stack uses.

Stability

The fields above are what a generator may rely on: route, instructions, stateVars, the six actions, components/props/slots, and showWhen. Anything else in a document is layout detail — nice to lower, not required.