Modyra is one framework-agnostic form engine (@modyra/core) with seven
thin adapters on top (Angular, React, Vue, Lit, Solid, Preact, Svelte).
Everything here is organized by what you are trying to do. New here?
Start with the main README, run a
framework example, then read the two core guides
(mental model → typed forms).
This same content is also published as a searchable site — see
../site/, generated from these files by
npm run docs:build (../scripts/sync-docs-site.mjs). Edit the markdown
here; the site is a build artifact, never hand-edited.
| Document |
What it covers |
| Main README |
Install, 60-second engine, real-world agnostic scenarios, packages |
| Framework examples |
The same checkout app across all 7 adapters |
| Usage modes |
Typed API vs declarative vs headless vs dynamic JSON — pick your mode |
| Document |
What it covers |
| Mental model |
The state graph, field lifecycle, operation semantics (set/patch/reset) |
| Typed forms |
Schema, handles, field arrays, async validation, drafts (security note), undo/redo, mutate(), construction/activation (SSR, Strict Mode), getChanges, wizard, Zod |
| Schema adapters |
@modyra/zod vs @modyra/standard-schema (Valibot, ArkType, …) — which model, which trade-offs |
| Server validation |
One schema, two sides — serverValidate() with Next.js/Express/Hono, tested runnable examples |
| Troubleshooting |
Why is canSubmit() false? Why is a field stuck in pending? |
The identical checkout — nested groups, typed array rows, cancellable
server validation, submit with server errors, drafts — in each binding:
- Angular —
mdyForm + UI catalog, @for over rows()
- React —
useMdyForm / useMdyField, headless controlled inputs
- Vue —
createVueForm on @vue/reactivity
- Lit —
createLitForm + <mdy-*-field> custom elements
- Solid —
useSolidForm, fields read as accessors, no hook needed
- Preact — identical shape to the React binding, thinner runtime
- Svelte —
createSvelteForm + toStore() for native $store bindings
| Document |
What it covers |
| Multi-framework architecture |
What’s in the agnostic @modyra/core, the MdyReactivity contract every adapter implements, per-adapter recipes (Angular/React/Vue/Lit/Solid/Preact/Svelte/Astro) |
| Reactive Forms interop |
mdyCva — embed Modyra controls in existing Angular Reactive Forms |
| Compared with Reactive Forms |
Honest trade-offs, migration paths |
| Compared with react-hook-form |
Side-by-side snippet (tested), the formState proxy gotcha, migration guidance |
| Compared with Formik |
Side-by-side snippet (tested), the isValid dirty-gating gotcha, migration guidance |
| Form library comparison |
Measured bundle sizes + feature matrix vs RHF, TanStack Form, Formik, Final Form, VeeValidate — updated 2026-07-21 |
| React Native |
Hermes-compatibility verification (real hermesc), what’s still missing for a real RN integration |
| Writing a reactivity adapter |
The MdyReactivity contract, capability honesty, ownership/scope, the conformance suite — for building the next framework adapter |
| Reactivity capability matrix |
Generated (not hand-maintained) table of what each adapter’s MdyReactivity actually declares — npm run docs:reactivity-matrix regenerates it |
| Document |
What it covers |
| UI toolkit |
Renderer catalog, enterprise select, dynamic forms, CSS tokens |
| AI-generated forms |
LLM output → parseDynamicFields() → render: JSON contract v1/v2 (layout, rules), system prompt template, safe pipeline |
| Injection prevention |
Sanitization profiles at the engine’s write choke point, violation telemetry, always-on draft/server structural checks |
| Headless recipes |
shadcn/ui, Radix, shadcn-vue/Reka: tested props-mappers from field handles to your component library |
| I18n |
UI strings (en/it/de/fr/es), date/time value models, localized parsing |
| DevTools |
Hotkey overlay, masking, production notes |
| Document |
What it covers |
| Security policy |
Threat model, reporting, draft/SSR notes |
| Contributing |
Setup, conventions, PR checklist |
| Trusted Publishing admin runbook |
npm OIDC setup, Changesets integration checks, staged release operations |
| Rust SDK |
modyra-contract crate (Dynamic Form Contract v2, shared fixtures), reqwest/Axum examples — not published to crates.io yet |
| Changelog |
Release history |
| Brand assets |
Logo, palette, typography |
- Guides (concept documentation) live in
docs/guides/ — one topic per
file, named after the topic (typed-forms.md, not guide2.md).
- Examples (runnable walkthroughs) live in
docs/examples/ — one
framework per file, same scenario across files so adapters compare
side by side.
- Every guide starts with a one-sentence summary and ends with links to
related guides. Code samples must match the public API of the current
release — treat them as compile-checked documentation.
- Package-level docs live next to the code (
packages/<name>/README.md)
and are what npm renders; the guides go deep, the READMEs stay
self-contained.