Svelte renderer
The @texaryn/svelte package renders a Texaryn UI document through Svelte 5
components. It bridges the framework-neutral runtime stores to readable stores.
Schema evaluation and validation remain in @texaryn/schema-json and
@texaryn/core.
Install
Section titled “Install”pnpm add @texaryn/core @texaryn/schema-json @texaryn/svelte svelteSvelte 5.20 or newer is required.
Create a form
Section titled “Create a form”Create the schema adapter before mounting the component tree. A parent
component creates the runtime, then FormRoot provides the renderer context to
its descendants.
import { mount } from 'svelte'import { createJsonSchemaAdapter } from '@texaryn/schema-json'import App from './App.svelte'
const adapter = await createJsonSchemaAdapter({ type: 'object', title: 'Profile', required: ['name'], properties: { name: { type: 'string', title: 'Name', minLength: 2 }, age: { type: 'integer', title: 'Age', minimum: 18 }, },})
mount(App, { target: document.getElementById('app')!, props: { adapter },})<script lang="ts"> import type { SchemaEvaluationPort } from '@texaryn/core' import { createDefaultRegistry, createForm, FormRoot } from '@texaryn/svelte'
let { adapter }: { adapter: SchemaEvaluationPort } = $props() const form = createForm(adapter, { initialData: { name: '', age: 18 } }) const data = form.data const registry = createDefaultRegistry()
function submit(event: SubmitEvent) { event.preventDefault() form.dispatch({ type: 'Submit' }) }</script>
<form novalidate onsubmit={submit}> <FormRoot {form} {registry} showErrorSummary> <h2>Data</h2> <pre>{JSON.stringify($data, null, 2)}</pre> </FormRoot> <button type="submit">Submit</button></form>FormRoot renders the active schema nodes and optional error summary, without
creating a native form. The application owns the form element and connects its
submit event to the runtime. FormRoot creates an id prefix from Svelte’s
component id for server rendering and hydration. Set an explicit idPrefix if
application code needs a stable value, and keep it unique among the forms on
the page. By default, FormRoot destroys the runtime when it unmounts. Set
destroyOnUnmount={false} when another owner manages the runtime.
Default widgets and messages
Section titled “Default widgets and messages”The default registry renders text, number, checkbox, enum, object, and array nodes. Field errors use a polite live region. The error summary focuses after a failed submission settles and links to each field control. Array controls add, remove, and reorder items when the corresponding UI hints allow those actions.
Pass a complete FormMessages object to FormRoot to replace the built-in
English messages. It remains the application’s responsibility to provide every
message function.
Custom widgets
Section titled “Custom widgets”A widget is a Svelte 5 component that accepts a node prop. Register it in a
RendererRegistry<WidgetComponent> and pass the registry to FormRoot.
Descendants can use useFormContext() to access the form, registry, messages,
and id prefix. Call it during component initialization below FormRoot.
<script lang="ts"> import type { UINode } from '@texaryn/core' import { useFormContext } from '@texaryn/svelte'
let { node }: { node: UINode } = $props() const { form } = useFormContext()</script>
<div data-node-id={node.id}>{node.annotations.title}</div>createFieldBinding adapts field state to readable stores for custom inputs.
The binding includes the field value, display value, label and description,
interaction state, visible errors, and ARIA attributes.
Data ownership
Section titled “Data ownership”createForm keeps Texaryn’s runtime as the source of form data and validation.
Svelte components observe its readable stores. The binding does not mirror
values into another form state library.