Why Formily?
Formily is not just a validation library; it is a complete form solution ecosystem based on the MVVM (Model-View-ViewModel) pattern. It addresses the specific pain points of enterprise applications where forms have hundreds of fields and complex inter-dependencies.
- Reactive Performance: Built on a distributed state management core (similar to MobX), it ensures that typing in one field only renders that specific component, maintaining high performance even with 1,000+ fields.
- Complex Linkage Logic: It provides a mechanism to handle "If Field A is X, then Field B is visible and required" scenarios through reactive effects, without turning your component code into spaghetti.
- JSON Schema Protocol: Formily treats JSON Schema as a first-class citizen, making it the go-to choice for "Low-Code" platforms or Server-Driven UI where forms are generated dynamically from backend configuration.
- UI Agnostic: The core logic is separated from the view layer. You can use it with React, Vue, or strictly via vanilla JavaScript, and it has official bindings for Ant Design, Element, and others.
- Domain Model Driven: It encourages defining your form's data structure and logic separately from the UI render, leading to more maintainable and testable code for large applications.
Code Snippet
This example demonstrates how Formily separates the Form Model (logic) from the UI. Notice how we define the form instance once, and the UI components simply bind to the model.
import React, { useMemo } from 'react'
import { createForm } from '@formily/core'
import { FormProvider, Field } from '@formily/react'
// 1. Define UI Components (Simplified wrapper)
const Input = ({ value, onChange, ...props }) => (
<input {...props} value={value || ''} onChange={(e) => onChange(e.target.value)} className="border p-2" />
)
export default function ComplexForm() {
// 2. Create the Form Model (The "Brain")
const form = useMemo(() => createForm({
effects() {
// 3. Define Logic: When 'username' changes, set 'bio'
/*
onFieldMount('username', (field) => {
// Reactive logic goes here
})
*/
}
}), [])
return (
<FormProvider form={form}>
<div className="flex flex-col gap-4">
{/* 4. Bind UI to Model */}
<div>
<label>Username</label>
<Field
name="username"
component={[Input, { placeholder: "Type here..." }]}
required
/>
</div>
<div>
<label>Bio</label>
<Field
name="bio"
component={[Input, { placeholder: "Tell us about yourself" }]}
/>
</div>
<button onClick={() => form.submit(console.log)}>Submit</button>
</div>
</FormProvider>
)
}
In a real-world Formily app, you would typically use SchemaField to render the entire form from a JSON object, drastically reducing the amount of JSX you need to write.
Pros and Cons
No library is perfect; understanding the trade-offs is key to selecting the right tool.
Pros
- Solution for Complexity: It solves the O(N) performance problem in forms with heavy linkage logic where standard React state management becomes slow or unmanageable.
- Schema Engine: Its ability to generate fully functional forms (including layout and validation) purely from JSON is unmatched in the ecosystem.
- Rich Ecosystem: It comes with ready-to-use adapter libraries for Ant Design, MUI, and NextUI, saving you from building basic field wrappers.
Cons
- Steep Learning Curve: The API surface is massive. Understanding concepts like "Observables," "Path System," and "Effects" takes significant time compared to hooks-based libraries.
- Abstraction Weight: It introduces a heavy layer of abstraction. Debugging issues often requires looking into the Formily "black box" rather than standard React props/state.
- Overkill for Most: For 90% of web forms (login, contact, simple settings), Formily is vastly over-engineered and adds unnecessary bundle size.
Comparison with Other Form Libraries
The table below outlines the positioning differences between Formily and other popular libraries:
| Library | Design Philosophy | Best For | Pain Points |
|---|---|---|---|
| Formily | Model-Driven / Reactive Treats forms as a data graph with reactive dependencies. | Enterprise SaaS / Low-Code Admin panels, dynamic configuration pages, and complex B2B workflows. | Complexity High cognitive load. Requires learning a specific DSL and architecture. |
| React Hook Form | Uncontrolled / Minimalist Focuses on raw performance and standard HTML inputs. | Standard Applications The vast majority of consumer-facing apps and static admin forms. | Dynamic Linkage Handling complex "A affects B affects C" logic requires manual useEffect chains. |
| RJSF | Schema-First / Rigid Strictly generates forms from standard JSON Schema. | Quick Prototypes Generating admin UIs where you don't care about pixel-perfect customization. | Customization Very hard to customize layout and interaction logic beyond the basics. |
Ecosystem & Extensions
Formily is a monorepo with several packages designed to work together:
@formily/core: The logic kernel (VM), independent of any framework.@formily/react: React bindings to connect the core to React components.@formily/antd/@formily/next: Pre-built component libraries that wrap Ant Design or Alibaba Fusion, allowing you to build forms instantly.