Skip to content

Architecture

Texaryn separates schema evaluation, state and rendering. An adapter reads the schema; the headless runtime owns behavior; a framework binding renders the result. Replacing a widget does not require reimplementing schema rules.

A form uses a version 1 UI document and FormRuntime. A standalone display uses a version 2 document and createDocumentRuntime, without a schema adapter. These are two document families, not successive versions of the same format. See What is Texaryn? for the full pipeline.

Package Responsibility
@texaryn/core The framework-neutral runtime: versioned UI documents, form commands, validation and submission lifecycle
@texaryn/collaboration-yjs Optional Yjs binding for shared scalar field values; the host supplies the document and provider
@texaryn/schema-json JSON Schema evaluation behind the schema port, across four dialects
@texaryn/schema-zod Zod 4 validation with projection through JSON Schema
@texaryn/react The React binding: form hooks, display documents and the default widgets
@texaryn/angular The Angular binding: signals, standalone form and display components
@texaryn/react-bootstrap Bootstrap 5 widgets over the React binding
@texaryn/react-mui Material UI v9 widgets over the React binding
@texaryn/vue The Vue 3 binding: form composables, display documents, and the default widgets
@texaryn/solid The SolidJS binding: signal subscriptions, display documents, and default widgets
@texaryn/svelte The Svelte 5 binding: readable store bridge, form and display components
@texaryn/web-components The custom element binding: form and display roots with native widgets in light DOM

Core never imports a schema library. It talks to a port that projects data into a SchemaProjection and validates it. @texaryn/schema-json is one implementation, which is what keeps JSON Schema from becoming an assumption rather than a choice. TypeBox supplies JSON Schema directly. The optional @texaryn/schema-zod package uses Zod for validation and the JSON Schema adapter for field projection.

The optional @texaryn/collaboration-yjs package stores a bootstrap snapshot and scalar overrides by JSON Pointer. Core stays independent of Yjs and transport code. The host supplies a Y.Doc and provider. Version 1 keeps array lengths and object properties fixed, so concurrent array ordering is outside this package’s contract.

flowchart LR
  accTitle: Collaborative scalar edits
  accDescr: FormRuntime sends committed scalar edits to the Yjs adapter, which keeps a baseline and pointer overrides in a Y.Doc that the host provider syncs.
  App[Host application] --> Runtime[FormRuntime]
  Runtime -->|committed scalar edits| Adapter["@texaryn/collaboration-yjs"]
  Adapter <-->|baseline and pointer overrides| Doc[Y.Doc]
  App --> Provider[Host selected provider]
  Provider <-->|Yjs updates| Doc

Every package versions on its own contract. A breaking change in the React binding does not make @texaryn/core a major, and a core major does not force one on bindings that absorb it without breaking their own API. Internal dependencies are caret ranges rather than exact pins, so a version describes a package rather than the state of the repository.

Each capability declares the layer its semantic proof belongs to.

  • Projection covers schema semantics: what a keyword does to the projected document.
  • Runtime covers behaviour over time: commands, validation triggers, array identity, submission.
  • Renderer covers what reaches the page, including accessibility, and is covered by shared conformance suites for React, Vue, Svelte and Web Components, plus dedicated Angular and SolidJS renderer suites.

Keeping those apart is what stops a renderer concern from being answered by a runtime test, or an accessibility claim from resting on one design system’s implementation.