A lightweight, type-safe form toolkit for React built with developer ergonomics in mind.
Formly provides a flexible form management solution with built-in validation, dynamic array manipulation, reactive computed fields, and multi-step wizard layouts—driven by a high-performance pub-sub event architecture.
- ⚡ Micro-Render Architecture: High-performance pub-sub event bus updates targeted inputs directly, completely bypassing full-form React re-renders.
- 🧩 100% Type-Safe: Auto-inferred nested paths, option cascades, normalizers, and wizard steps.
- ✅ First-Class Schema Validation: Native, seamless integration with Zod schemas.
- 📋 Auto-Keyed Dynamic Arrays: Lists tracked via parallel, persistent unique keys for perfect React reconciliation and smooth animations.
- 🧮 Dynamic Computed Fields: Derive values reactively from other form fields or external React state.
- 🧹 Declarative Input Normalization: Format and sanitize values (e.g., phone formatting, uppercasing) in real-time as users type.
- 📊 Patch Payload Diffing (
getChanges): Extract and submit only modified fields to keep API requests lightweight. - 💾 Zero-Config Draft Persistence: Automatically backup and restore form states across page reloads.
- 🛡️ Page Unload Prevention (
preventUnload): Stop users from losing unsaved edits by blocking accidental navigation/tab close when the form is dirty. - 🛠️ Zero-Setup Interactive DevTools: Floating debugger suite featuring live values, diff monitoring, and time-travel history.
Visit our documentation portal for complete guides, API references, computed fields, multi-step wizards, cascading dropdowns, and interactive devtools:
# npm
npm install @explita/formly
# yarn
yarn add @explita/formly
# pnpm
pnpm add @explita/formlyEnsure react, react-dom (v19+ recommended), and zod are installed as peer dependencies.
import { Form, Field, useForm } from "@explita/formly";
import { z } from "zod";
const formSchema = z.object({
username: z.string().min(3, "Username must be at least 3 characters"),
email: z.string().email("Invalid email"),
});
function UserForm() {
const form = useForm({
defaultValues: { username: "", email: "" },
schema: formSchema,
onSubmit: (values, ctx) => {
console.log("Submitted values:", values);
console.log("Changes (PATCH payload):", ctx.getChanges());
},
});
return (
<Form use={form}>
<form.Field
name="username"
label="Username"
render={(props) => <input {...props} />}
/>
<form.Field
name="email"
label="Email Address"
render={(props) => <input {...props} type="email" />}
/>
<button type="submit">Submit</button>
</Form>
);
}Formly is built to make form management in React simple, type-safe, and performant. If it has improved your developer experience or helped you build complex forms faster, please consider supporting the project to ensure its continued growth and maintenance!
- Give us a ⭐: It helps others discover the project.
- Join the Discussion: Report bugs or suggest new features.
- Spread the Word: Share your experience with Formly on social media.
A huge thank you to everyone helping us build the future of React forms!
MIT © Explita