Skip to content

Getting started

This example renders a profile form with a required name and a newsletter checkbox. Invalid submissions show errors; valid submissions log the data to the browser console.

Using another framework? Choose your packages links to setup for all six bindings.

In an existing React TypeScript application, add:

Terminal window
pnpm add @texaryn/core @texaryn/schema-json @texaryn/react

React 18.3 and React 19 are supported. The core, JSON Schema adapter and React binding are at 1.0. See package stability for the other bindings and adapters.

Replace src/main.tsx with the following code. Your page must contain <div id="root"></div>. For example, the Vite React TypeScript template provides that element.

import { createRoot } from 'react-dom/client'
import { createJsonSchemaAdapter } from '@texaryn/schema-json'
import {
ErrorSummary, FormProvider, FormRoot, createDefaultRegistry, useForm,
} from '@texaryn/react'
async function main() {
const adapter = await createJsonSchemaAdapter({
$schema: 'https://json-schema.org/draft/2020-12/schema',
type: 'object',
title: 'Profile',
required: ['name'],
properties: {
name: { type: 'string', title: 'Name', minLength: 2 },
newsletter: { type: 'boolean', title: 'Subscribe to newsletter' },
},
})
const registry = createDefaultRegistry()
function App() {
const form = useForm(adapter, {
initialData: { name: '', newsletter: false },
onSubmit: (data) => console.log('Submitted', data),
})
return (
<FormProvider value={form.runtime}>
<form noValidate onSubmit={(event) => {
event.preventDefault()
form.dispatch({ type: 'Submit' })
}}>
<ErrorSummary />
<FormRoot registry={registry} />
<button type="submit">Submit</button>
</form>
</FormProvider>
)
}
createRoot(document.getElementById('root')!).render(<App />)
}
void main()

Start your application’s development server. Submit an empty name: the error summary takes focus and links to the name field. Enter at least two characters and submit again: onSubmit logs the form data. Replace that callback with your application’s save function when connecting a backend.

FormRoot renders the field tree, not a native form. The application owns <form>, prevents its default navigation, and dispatches Submit. This also supports submission with Enter. noValidate leaves validation to Texaryn.

An object with several properties of different types, rendered as one group.

  • Object types
  • String fields
  • Integer fields

The schema defines the data contract. UI hints choose how a field is presented and when it is validated. Add hints to the useForm options:

hints: {
'/name': {
placeholder: 'Your full name',
helpText: 'Use at least two characters.',
validationTrigger: 'blur',
},
},

Hint keys are JSON Pointers: /name addresses the top-level name property. The hint does not change the schema’s minLength constraint.

initialData supplies starting values. A schema’s default annotations do not populate the form unless schema-default initialization is explicitly requested. See initialization for that option and its limits.