Formly v0.3.1 is officially here

Micro-Renders.Absolute Type-Safety.

A high-performance form state & validation toolkit for React. Bypasses general re-renders using a reactive pub-sub architecture—built with Zod and developer ergonomics in mind.

~25KB Bundle Size (Gzipped)
Zero Unnecessary Re-Renders
100% Declarative Zod Integration

Supercharged Developer Experience

Formly eliminates standard boilerplate and rendering bottlenecks. Get access to complete control structures right out of the box.

Micro-Render Architecture

Built on a targeted pub-sub event bus. State changes channel directly to inputs, completely bypassing React's standard full-form re-renders.

Zod Schema Validation

Validate entire schemas or individual paths reactively. Support customized error message parsers and automated error focus controls.

Zero-Config DevTools

Inspect form state visually using the visual element picker, copy state diffs instantly, and rollback edits with the built-in time travel timeline.

Stable-Keyed Arrays

Automate dynamic list item keys. Formly generates persistent list keys that stay in sync during array sorting, shifting, and removal operations.

Draft State Persistence

Backup unsaved forms instantly to local storage. Enable preventUnload prompts to block users from accidentally refreshing or losing data.

Reactive Normalizers

Sanitize, trim, and format form inputs in real-time. Automatically normalize values (e.g. phone masks, upper casing) as users type.

Three Steps to a Form

Define your validation schema once, then wire it up with clean, type-safe components.

1

Define Schema

import { z } from "zod";

const schema = z.object({
  email: z.string().email(),
  age: z.number().min(18),
});

Create a Zod schema describing your form data shape and validation rules.

2

Create Form

const form = useForm({
  schema,
  defaultValues: { email: "", age: 18 },
  onSubmit: (values) => api.submit(values),
});

Call useForm with your schema and defaults. Returns a fully typed form controller.

3

Render Fields

<Form use={form}>
  <form.Field name="email"
    render={(props) => <Input {...props} />}
  />
</Form>

Render fields with the <Form> component. Each update targets only the changing input.

Two Ways to Use Formly

Choose headless hooks for full control, or the complete Form component for zero-config richness — or mix both.

Headless Hooks

Full control over your UI

  • Use useForm() independently — no UI dependency
  • Bring your own input components and styling
  • Perfect for custom design systems
  • Same reactive pub-sub performance
Best for: Custom UI, design systems, minimal dependencies

Full <Form> Component

Built-in DevTools & ergonomics

  • Drop-in <Form> component with field scoping
  • Built-in DevTools bubble for live debugging
  • Auto-focus on first error, dirty tracking, submit handling
  • Zero-config — works out of the box
Best for: Rapid development, built-in debugging & validation UX

See It In Action

Clean syntax paired with peak rendering performance. Open your browser console to verify: inputs update directly without rendering the container layout.

MyForm.tsx
React TSX
import { useForm, Form } from "@explita/formly"; import { z } from "zod"; const formSchema = z.object({ fullName: z.string().min(3, "Min 3 chars"), email: z.string().email("Invalid email"), }); export default function Demo() { const form = useForm({ schema: formSchema, defaultValues: { fullName: "", email: "" }, onSubmit: (values) => sendToAPI(values), }); return ( <Form use={form}> <form.Field name="fullName" render={(props) => ( <input {...props} /> )} /> {/* Targeted channel render update! */} </Form> ); }

Live Formly Instance

Submit and modify inputs below to inspect real-time form state parameters.


Interactive DevTools Active!

Observe the floating Formly DevTools bubble in the bottom-right corner! Type into the inputs above and notice how the DevTools track live dirty states, validate schema criteria, and register event changes with zero container component re-renders.

Ready to Simplify Your Forms?

Install, define a schema, and wire up your form. No boilerplate, no unnecessary re-renders.

npm install @explita/formly