08 · Frontend
Does it work with React: components, hooks, and Context?
React is built in. A component compiles to a React function
component, JSX lowers to createElement, custom hooks are just functions,
and complex state is safer than plain TypeScript.
Why it matters
A lot of the code agents write is React. Glyph treats it as a first-class target, not a
bolt-on: component is its own keyword (so grep "^component "
audits your whole UI), and hooks work exactly as you'd expect because they're ordinary
function calls.
See it
A custom hook is a function that calls hooks. Reducer state gets something React alone can't give you, compile-time exhaustiveness on every action:
type Action = Inc | Dec | Reset
fn reducer(n: number, a: Action) -> number {
return match a {
Inc => n + 1,
Dec => n - 1,
Reset => 0,
// add an Action variant ⇒ this match fails to compile
}
}
fn use_counter() -> StateHandle<number> {
return use_reducer(reducer, 0)
}
Add a SetTo(number) action and every reducer that doesn't handle it stops
compiling: the bug a plain TypeScript switch would let ship. React
Context works today through createContext /
useContext, and member-expression element names
(<ThemeContext.Provider>) work directly: no workaround.
JSX prop spreading works too: <input {...register("email")} /> lowers
to an object spread in the props, so the react-hook-form idiom needs no adapter. Zod's
value-derived types are first-class: type FormData = z.infer<typeof schema>
works directly, no escape hatch. The one thing that differs: a component takes a
single props record, not multiple positional params. See
using your libraries and the
hardening page for exactly where that boundary is.
Are props checked before tsc?
Yes. Glyph compares each element with its component's props record itself, so a wrong value, a misspelled prop and a missing required one are Glyph errors that name the prop. You see them in the editor and over MCP, not only in a full build. It works the same whether the component was imported by name or through its module:
Card declared in ui.glyph
import ui
pub component App() {
return <div>
<ui.Card title="Q3" />
<ui.Card title="Q4" cout={2} />
</div>
}
// E0211 argument type mismatch: expected `CardProps`, found `record`: missing field `count`
// E0210 type `CardProps` has no field `cout`
// E0211 argument type mismatch: expected `CardProps`, found `record`: missing field `count`
--json carries the missing names as a missing_fields list, so
an agent can add the props without parsing the message. A component also has to take
its props as one record: component Greeting(name: string) is E0229 at the
parameter, because React only ever passes the props object and that element could never
type-check. If you call it as a function rather than render it, declare it with
fn.
Where it stands
Shipping today
Components, JSX, fragments (<>...</>), member-expression element names (<Ctx.Provider>), JSX prop spread ({...register()}), props checked against the component before tsc under every import spelling, built-in and custom hooks, useReducer with exhaustive tagged-union actions, and Context via createContext/useContext.
On the way
A Context primitive story for effectful custom hooks that composes with the JSX-purity rule, so more of the React-library surface works without a shim. A props type written inline still shows as record in these messages; a named one shows its name.