Prototyper UI

API Reference

Complete API reference for @prototyperai/stream-ui

This is the full API reference for @prototyperai/stream-ui, organized by import path.

Main Entry

import { ... } from "@prototyperai/stream-ui"

The main entry re-exports everything from core, catalog, and react, plus:

ExportTypeDescription
prototyperComponentsComponentRegistryPre-built registry of 20 Prototyper UI component renderers
specToJSX(spec, options?)FunctionConvert a spec to copy-paste JSX code

Core

import { ... } from "@prototyperai/stream-ui/core"

Types

Spec & Elements

Prop

Type

UIElement

Prop

Type

Expression Types

All 8 expression types that can appear in prop values:

TypeShapeDescription
StateExpression{ $state: string }Read from global state by JSON Pointer path
ItemExpression{ $item: string }Read from current repeat item ("" for whole item)
IndexExpression{ $index: true }Current repeat index (zero-based)
BindStateExpression{ $bindState: string }Two-way binding to global state path
BindItemExpression{ $bindItem: string }Two-way binding to repeat item field
CondExpression{ $cond, $then, $else? }Conditional value based on a visibility condition
ComputedExpression{ $computed: string, args? }Call a registered computed function
TemplateExpression{ $template: string }String interpolation with ${/path} references

The union type Expression includes all 8. DynamicValue<T> is T | Expression. Convenience aliases: DynamicString, DynamicNumber, DynamicBoolean.

VisibilityCondition

type VisibilityCondition =
  | boolean
  | SingleCondition
  | SingleCondition[]           // implicit AND
  | { $and: VisibilityCondition[] }
  | { $or: VisibilityCondition[] }

SingleCondition is StateCondition | ItemCondition | IndexCondition, each supporting comparison operators: eq, neq, gt, gte, lt, lte, not.

RepeatBinding

Prop

Type

ComparisonValue

A numeric comparison value used in visibility conditions. Can be a literal number or a dynamic state reference:

type ComparisonValue = number | { $state: string }

Used by the gt, gte, lt, and lte operators on visibility conditions and in the visibility helper functions.

ActionBinding

Prop

Type

ActionOnSuccess

Follow-up action to run on success. One of three variants:

type ActionOnSuccess =
  | { navigate: string }                                      // Redirect to a URL
  | { set: Record<string, unknown> }                          // Set state values
  | { action: string; params?: Record<string, DynamicValue<unknown>> }  // Chain another action

ActionOnError

Follow-up action to run on error. One of two variants:

type ActionOnError =
  | { set: Record<string, unknown> }                          // Set state values
  | { action: string; params?: Record<string, DynamicValue<unknown>> }  // Chain another action

FlatElement

A UIElement enriched with its own key and optional parent key. Useful for tree traversal and debugging:

interface FlatElement extends UIElement {
  key: string
  parentKey?: string | null
}

ActionConfirm

Prop

Type

ValidationCheck

Prop

Type

ValidationConfig

Prop

Type

StateStore

Prop

Type

JsonPatch

Prop

Type

Path Utilities

FunctionSignatureDescription
getByPath(obj: unknown, path: string) => unknownGet a value by JSON Pointer path
setByPath(obj: Record, path: string, value: unknown) => voidSet a value by path (mutating)
addByPath(obj: Record, path: string, value: unknown) => voidAdd per RFC 6902 semantics (array splice)
removeByPath(obj: Record, path: string) => voidRemove per RFC 6902 semantics
parseJsonPointer(pointer: string) => string[]Parse a JSON Pointer into unescaped segments

Patch Utilities

FunctionSignatureDescription
applyPatch(target: Record, patch: JsonPatch) => voidApply a single RFC 6902 patch operation
applyPatches(target: Record, patches: JsonPatch[]) => voidApply multiple patches in order
deepEqual(a: unknown, b: unknown) => booleanDeep equality check (used by test operations)

State

FunctionSignatureDescription
createStateStore(initialState: Record) => StateStoreCreate an in-memory state store with change notification
immutableSetByPath(obj: Record, path: string, value: unknown) => RecordImmutable set (returns new object)
flattenToPointers(obj: Record, prefix?: string, maxDepth?: number) => Record<string, unknown>Flatten a nested object into a flat map of JSON Pointer paths to values

Store Adapter

Bridge an external state store (Zustand, Redux, Jotai, etc.) to the StateStore interface:

FunctionSignatureDescription
createStoreAdapter(config: StoreAdapterConfig) => StateStoreCreate a StateStore adapter wrapping an external store

StoreAdapterConfig

Prop

Type

Prop Resolution

FunctionSignatureDescription
resolvePropValue(value: unknown, ctx: PropResolutionContext) => unknownResolve a single prop value (handles all 8 expression types)
resolveElementProps(props: Record, ctx: PropResolutionContext) => RecordResolve all props in an element
resolveBindings(props: Record, ctx?: PropResolutionContext) => Record<string, string>Extract $bindState/$bindItem paths from props
resolveActionParam(value: unknown, ctx: PropResolutionContext) => unknownResolve action param ($item yields path, not value)

PropResolutionContext

Prop

Type

Type guard functions are exported for each expression type: isStateExpression, isItemExpression, isIndexExpression, isBindStateExpression, isBindItemExpression, isCondExpression, isComputedExpression, isTemplateExpression.

Visibility

FunctionSignatureDescription
evaluateVisibility(condition: VisibilityCondition, ctx: VisibilityContext) => booleanEvaluate a visibility condition
evaluateCondition(condition: SingleCondition, ctx: VisibilityContext) => booleanEvaluate a single condition

VisibilityContext

Prop

Type

Type guards: isStateCondition, isItemCondition, isIndexCondition, isAndCondition, isOrCondition, isSingleCondition.

visibility.item

Convenience helpers for building ItemCondition objects inside repeat contexts:

MethodSignatureDescription
visibility.item.when(field: string) => ItemConditionTruthy check on an item field
visibility.item.unless(field: string) => ItemConditionFalsy check (not: true)
visibility.item.eq(field: string, value: unknown) => ItemConditionItem field equals value
visibility.item.neq(field: string, value: unknown) => ItemConditionItem field not equal
visibility.item.gt(field: string, value: ComparisonValue) => ItemConditionGreater than
visibility.item.gte(field: string, value: ComparisonValue) => ItemConditionGreater than or equal
visibility.item.lt(field: string, value: ComparisonValue) => ItemConditionLess than
visibility.item.lte(field: string, value: ComparisonValue) => ItemConditionLess than or equal

visibility.index

Convenience helpers for building IndexCondition objects inside repeat contexts:

MethodSignatureDescription
visibility.index.eq(value: number) => IndexConditionIndex equals value
visibility.index.neq(value: number) => IndexConditionIndex not equal
visibility.index.gt(value: number) => IndexConditionIndex greater than
visibility.index.gte(value: number) => IndexConditionIndex greater than or equal
visibility.index.lt(value: number) => IndexConditionIndex less than
visibility.index.lte(value: number) => IndexConditionIndex less than or equal

Actions

FunctionSignatureDescription
resolveAction(binding: ActionBinding, stateModel: StateModel) => ResolvedActionResolve dynamic params and interpolate strings
executeAction(resolved: ResolvedAction, handlers: Record, ctx: ActionExecutionContext) => Promise<void>Execute a resolved action with chaining
interpolateString(template: string, stateModel: StateModel) => stringReplace ${/path} references in a string
builtInActionsRecord<string, ActionHandler>Default handlers: setState, pushState, removeState, toggleState, navigate

ActionExecutionContext

Prop

Type

Built-in Actions

ActionParamsDescription
setState{ path, value }Set a value at a state path
pushState{ path, value }Append to a state array
removeState{ path, index }Remove from a state array by index
toggleState{ path }Toggle a boolean at a state path
navigate{ url }Navigate via ctx.navigate

Action Helpers

The actionBinding object provides convenience constructors for building ActionBinding objects:

MethodSignatureDescription
actionBinding.simple(action: string, params?: Record) => ActionBindingSimple action with optional params
actionBinding.withConfirm(action: string, confirm: ActionConfirm, params?: Record) => ActionBindingAction with confirmation dialog
actionBinding.withSuccess(action: string, onSuccess: ActionOnSuccess, params?: Record) => ActionBindingAction with success handler
actionBinding.withError(action: string, onError: ActionOnError, params?: Record) => ActionBindingAction with error handler
actionBinding.setState(path: string, value: unknown) => ActionBindingSet a state value
actionBinding.pushState(path: string, value: unknown) => ActionBindingAppend to a state array
actionBinding.removeState(path: string, index: unknown) => ActionBindingRemove from a state array by index
actionBinding.toggleState(path: string) => ActionBindingToggle a boolean
actionBinding.navigate(url: string) => ActionBindingNavigate to a URL

Check Helpers

The check object provides convenience constructors for building ValidationCheck objects with sensible default messages:

MethodSignatureDescription
check.required(message?: string) => ValidationCheckRequired field
check.email(message?: string) => ValidationCheckEmail format
check.minLength(min: number, message?: string) => ValidationCheckMinimum string/array length
check.maxLength(max: number, message?: string) => ValidationCheckMaximum string/array length
check.pattern(pattern: string, message?: string) => ValidationCheckRegex pattern match
check.min(min: number | { $state: string }, message?: string) => ValidationCheckMinimum numeric value (supports dynamic)
check.max(max: number | { $state: string }, message?: string) => ValidationCheckMaximum numeric value (supports dynamic)
check.numeric(message?: string) => ValidationCheckMust be a number
check.url(message?: string) => ValidationCheckURL format
check.matches(statePath: string, message?: string) => ValidationCheckMust match value at state path
check.equalTo(value: unknown, message?: string) => ValidationCheckMust equal a specific value
check.lessThan(statePath: string, message?: string) => ValidationCheckMust be less than value at state path
check.greaterThan(statePath: string, message?: string) => ValidationCheckMust be greater than value at state path
check.requiredIf(fieldPath: string, message?: string) => ValidationCheckRequired when field is truthy

Validation

FunctionSignatureDescription
runValidation(checks, value, customValidators?, ctx?, evaluateEnabled?) => ValidationResultRun all checks and collect errors
runValidationCheck(check, value, customValidators?, ctx?, evaluateEnabled?) => ValidationCheckResultRun a single check
builtInValidatorsRecord<string, ValidationFunction>14 built-in validator functions

ValidationResult

Prop

Type

Streaming

Function / TypeSignatureDescription
createStreamCompiler() => StreamCompilerCreate a stateful JSONL stream compiler
parseStreamLine(line: string) => JsonPatch | nullParse a single JSONL line into a patch
nestedToFlat(tree: Record) => SpecConvert a nested element tree to flat spec format

StreamCompiler

Prop

Type


React

import { ... } from "@prototyperai/stream-ui/react"
// or from the main entry:
import { ... } from "@prototyperai/stream-ui"

Renderer

The top-level component that renders a spec.

<Renderer
  spec={spec}
  registry={registry}
  handlers={customHandlers}
  functions={computedFunctions}
  navigate={(url) => router.push(url)}
  onConfirm={(confirm) => window.confirm(confirm.message)}
  onStateChange={(state) => console.log(state)}
  loading={isStreaming}
/>

Prop

Type

StreamUIProvider

Composes all context providers. Use this when you need to render elements manually or access hooks outside the Renderer.

<StreamUIProvider spec={spec} registry={registry} handlers={handlers}>
  <ElementRenderer elementKey={spec.root} />
</StreamUIProvider>

Props are the same as RendererProps plus children, minus loading.

ElementRenderer

Renders a single element by its key. Must be used inside a StreamUIProvider.

<ElementRenderer elementKey="myElement" loading={false} />

ComponentRenderProps

Props passed to each component renderer function:

Prop

Type

Hooks

useUIStream

Connect to a streaming JSONL endpoint:

const { spec, isStreaming, error, send, clear } = useUIStream({
  url: "/api/generate-ui",
  method: "POST",
  autoStart: false,
})

Prop

Type

Returns:

Prop

Type

useBoundProp

Two-way binding for a single prop value:

const [value, setValue] = useBoundProp<string>(propValue, bindingPath)

When bindingPath is provided and the component is inside a StreamUIProvider, reads/writes go through the state store. Otherwise, falls back to local state.

useStateBinding

Direct two-way binding to a state path:

const [value, setValue] = useStateBinding<number>("/counter")

Must be used inside a StreamUIProvider.

useFieldValidation

Client-side field validation tied to a state path:

const { errors, validate, touch, clear } = useFieldValidation("/form/email", {
  checks: [
    { validator: "required", message: "Required" },
    { validator: "email", message: "Invalid email" },
  ],
  validateOn: "change",
})

See the Validation page for full documentation.

DevTools

StreamUIDevTools

Debug overlay with spec tree, state inspector, and action log.

<StreamUIDevTools defaultOpen={false} actionLog={externalLog} />

See the DevTools page for full documentation.

useDevToolsActionLog

Hook for external action logging:

const { log, record, clear } = useDevToolsActionLog()

Context Hooks

HookReturnsDescription
useStreamUIState(){ store, snapshot }Access the state store and current snapshot
useStreamUIStateOptional(){ store, snapshot } | nullSafe version that returns null outside provider
useStreamUIActions()ActionContextValueAccess action handlers and execution
useRepeatScope(){ repeatItem, repeatIndex, repeatBasePath } | nullAccess current repeat scope
useStreamUIFunctions()Record<string, ComputedFunction>Access registered computed functions
useSpecContext(){ spec, registry }Access the current spec and component registry

Catalog

import { ... } from "@prototyperai/stream-ui/catalog"

Builder Functions

FunctionSignatureDescription
defineComponent(def: ComponentDefinition<T>) => ComponentDefinition<T>Define a component with type inference
defineAction(def: ActionDefinition<T>) => ActionDefinition<T>Define an action with type inference
defineCatalog(config: CatalogConfig) => CatalogCreate a compiled catalog
defineRegistry(catalog: Catalog, componentMap: Record<string, R>) => Registry<R>Wire catalog to React renderers

Schema Utilities

Function / TypeSignatureDescription
buildSpecZodSchema(catalog: Catalog) => z.ZodTypeBuild a Zod schema that validates a complete Spec against a catalog
validateElementProps(element: { type, props }, catalog: Catalog) => { valid, errors }Validate an element's literal props against its component schema (expressions are stripped)
expressionSchemaz.ZodTypeZod schema matching any of the 8 expression types
visibilityConditionSchemaz.ZodTypeZod schema matching any visibility condition
dynamicOf<T>(baseSchema: z.ZodType<T>) => z.ZodTypeWrap a base schema to also accept expression objects

Type Inference

Type-level utilities for extracting TypeScript types from catalog definitions:

import type {
  InferCatalogComponents,
  InferCatalogActions,
  InferComponentProps,
  InferActionParams,
} from "@prototyperai/stream-ui/catalog"
TypeDescription
InferCatalogComponents<C>Extract the components map type from a Catalog
InferCatalogActions<C>Extract the actions map type from a Catalog
InferComponentProps<C, K>Extract the inferred props type for component name K
InferActionParams<C, K>Extract the inferred params type for action name K

Spec Builder

import { createSpecBuilder } from "@prototyperai/stream-ui/catalog"

const builder = createSpecBuilder(catalog)

const { key, element } = builder.element("submitBtn", "Button", { label: "Submit" }, {
  on: { press: { action: "submitForm" } },
})

const spec = builder.spec("root", { root: rootElement, submitBtn: element })
FunctionSignatureDescription
createSpecBuilder(catalog: Catalog) => SpecBuilderCreate a type-safe spec builder for programmatic spec construction

Prompt Generation

FunctionSignatureDescription
buildSystemPrompt(catalog: Catalog, options?: PromptOptions) => stringGenerate a complete LLM system prompt
buildUserPrompt(prompt: string, options?: UserPromptOptions) => stringWrap a user prompt with optional context

UserPromptOptions

Prop

Type

PromptOptions

Options for customizing prompt generation:

Prop

Type

PromptTemplate

A function that generates a prompt string from context:

type PromptTemplate = (context: PromptContext) => string

PromptContext

Context passed to a prompt template function:

Prop

Type

CatalogValidationResult

Result of catalog.validate(spec):

Prop

Type

SpecIssue

A single issue found during spec validation:

Prop

Type

See the Catalog page for full documentation.


Codegen

import { specToJSX } from "@prototyperai/stream-ui"
// or
import { specToJSX } from "@prototyperai/stream-ui/codegen"
FunctionSignatureDescription
specToJSX(spec: Spec, options?: CodegenOptions) => stringConvert a spec to JSX source code

CodegenOptions

Prop

Type

See the Code Export page for full documentation.


Components

import { prototyperComponents } from "@prototyperai/stream-ui/components"

prototyperComponents is a ComponentRegistry containing renderers for 20 Prototyper UI components:

Button, Card, CardContent, CardHeader, CardTitle, CardDescription, CardFooter, Heading, Text, Input, Textarea, Select, Checkbox, Switch, RadioGroup, Tabs, TabsList, TabsTrigger, TabsContent, Dialog, Accordion, Slider, Avatar, Separator, Progress, Tooltip, Badge, Alert.

Each renderer wraps the corresponding Prototyper UI component, mapping the ComponentRenderProps interface to the component's native props, handling two-way bindings, and forwarding events.

On this page