Formwright
Schema-driven form engine for React. Define your form once as a schema — Formwright handles conditional logic, layout, validation, and data sources at runtime.
npm install formwright@latest react-hook-form
What it does
You define fields, layout, and rules declaratively. At runtime, Formwright evaluates those rules against current form values and keeps field visibility, required state, and disabled state in sync automatically — without you writing any conditional rendering code.
import { defineForm, field, layout, rule, fieldRef, buildForm } from "formwright/schema";
import { createFormRuntime } from "formwright/core";
import { FormRuntimeProvider, FormRuntimeRoot } from "formwright/react";
import { registerBasicPlugins } from "formwright/plugins";
const form = buildForm({
form: defineForm({ id: "contact" }),
fields: [
field.select("type", { label: "Contact type", options: [
{ value: "individual", label: "Individual" },
{ value: "company", label: "Company" },
]}),
field.text("name", { label: "Full name", required: true }),
field.text("companyName", { label: "Company name" }),
],
layout: layout.stack("root", [
layout.field("type"),
layout.field("name"),
layout.field("companyName"),
]),
rules: [
rule.when(fieldRef("type").eq("company")).show("companyName"),
rule.when(fieldRef("type").eq("individual")).hide("companyName"),
],
});
const runtime = createFormRuntime({ form, plugins: registerBasicPlugins() });
export function ContactForm() {
return (
<FormRuntimeProvider runtime={runtime}>
<FormRuntimeRoot rootLayoutId="root" />
</FormRuntimeProvider>
);
}
Key capabilities
- Conditional logic — show/hide, enable/disable, require fields based on other field values or runtime context
- Bring your own UI — plug in shadcn/ui, Radix, or any component library via renderer maps and slots
- Validation — schema-driven RHF rules or custom resolvers (Zod, Yup)
- Data sources — static inline options or async remote APIs with loading state
- Remote schemas — validate and render backend-provided form definitions
- Plugin system — extend with custom field types, operators, effects, and data sources
- TypeScript-first — fully typed schema, runtime, and renderer APIs
Start here
| I want to... | Go to |
|---|---|
| Get a form rendering in 5 minutes | Quick Start |
| Understand how it works | Mental Model |
| Add conditional field logic | Conditional Fields |
| Use my design system components | Customization |
| Add Zod validation | Validation |
| Load options from an API | Data Sources |
| Render schemas from my backend | Remote Schemas |
| See the full API | API Reference |