Migrating from RJSF
This guide maps react-jsonschema-form concepts to their Texaryn equivalents and lists the steps for porting a form.
It describes Texaryn’s behaviour precisely and compares against RJSF’s public concepts. It deliberately does not document RJSF’s internals, which are theirs to change.
Concept map
Section titled “Concept map”| RJSF | Texaryn |
|---|---|
schema prop |
createJsonSchemaAdapter(schema) |
uiSchema |
UI hints keyed by JSON Pointer |
formData / onChange |
initialData option, data store |
| widgets, templates, fields | renderer registry, WidgetComponent, NodeRenderer |
| array rendering | useFieldArray with stable item identity |
validate, customValidate, liveValidate |
schema adapter validation, validationTrigger hints |
onSubmit |
onSubmit option plus the submission lifecycle |
showErrorList / ErrorList |
visibleErrors store, ErrorSummary component |
transformErrors |
no equivalent |
Key differences
Section titled “Key differences”Schema evaluation is separate from the runtime. In RJSF, Form processes
the schema, manages state and renders. In Texaryn a schema adapter produces a
SchemaEvaluationPort that the runtime consumes, the runtime owns state, and
the renderer maps UI nodes to components. Those three concerns are
independent, which is what allows a second schema language or a second
framework without touching the others.
The core is framework neutral. @texaryn/core does not depend on React.
@texaryn/react is one binding over it. RJSF is React only.
State is reactive rather than a single mutable object. Renderers subscribe to stores, and edits produce new snapshots rather than mutating in place.
Array items keep a stable identity. Texaryn assigns each item an identity that follows the item rather than its index, so removing the first row does not hand its identity to the second, and per-row component state stays attached to the right row.
By default two items are considered the same when Object.is matches, and for
objects when their JSON serialization matches. That means two structurally
identical rows are indistinguishable, which is exactly when you want the
itemKey hint: it names a property that identifies a row, so identity follows
that value instead.
Add and remove rows and watch the identity of the surviving rows. Removing the first item must not hand its identity to the second, which is what keeps focus and per-item state attached to the right row.
- Add an array item
- Remove an array item
- Stable array item identity
- Array types
Validation triggers are per field. Each field’s validationTrigger hint
('blur', 'change' or 'submit') decides when validation runs, with
configurable debounce. When a matching blur or change occurs, Texaryn
validates the full form snapshot and distributes errors back to nodes by JSON
Pointer.
Three fields, each validated at a different moment. Change validates as you type, blur waits until you leave the field, and submit holds everything until the form is submitted.
- Validate on change
- Validate on blur
- Validate on submit
- minLength
Submission is a state machine. Submission moves through idle,
validating, submitting and submitted, with snapshot semantics and
cancellation, rather than calling a handler straight after validation.
Submitting validates first and only proceeds when the form is valid. A required field left empty blocks submission and surfaces the error instead.
- Submission lifecycle
- Required and optional fields
Migration checklist
Section titled “Migration checklist”-
Inventory your
uiSchema. Map eachui:key to a Texaryn hint at the matching JSON Pointer.uiSchema: { email: { 'ui:placeholder': '...' } }becomeshints: { '/email': { placeholder: '...' } }. -
Register custom widgets. Implement RJSF widgets or templates as
WidgetComponententries in a renderer registry.NodeRendererdispatches to the registry by semantic type and widget hint. -
Replace
formDataplumbing. Drop theformDataprop andonChangehandler. PassinitialDatatouseFormorcreateFormRuntime, and read live data fromform.dataorruntime.data. -
Port validation. Remove
validate,customValidateandliveValidate. SetvalidationTriggerper field. The schema adapter handles standard JSON Schema validation; validation beyond the schema has no equivalent yet. -
Port submission. Replace the
onSubmitprop with theonSubmitoption, dispatch{ type: 'Submit' }from a button, and readform.submission.statusandform.submission.errorfor feedback. -
Review array identity. Test reordering and removal. Reach for the
itemKeyhint when rows are structurally similar. -
Review accessibility. The prop getters (
getInputProps,getLabelProps,getErrorProps,getDescriptionProps) setaria-invalidandaria-describedbyfor you. Remove manual ARIA attributes from custom widgets rather than duplicating them.
What has no equivalent
Section titled “What has no equivalent”transformErrors: error message customization is not available.extraErrors: injecting server-side errors after validation is not supported.formContext: use React context or component props directly.ObjectFieldTemplateandArrayFieldTemplate: use a renderer registry withWidgetComponententries instead.
See Getting started for a complete working example.