Why RJSF vs FormEngine?
When we developed FormEngine, we often heard: "How are you different from react-jsonschema-form?"
Fair question. Both libraries:
- React-based
- Work with JSON: RJSF uses JSON Schema to describe forms, FormEngine uses its own JSON format
- Support Material UI
- Open to customization
But there's one fundamental architectural difference that radically affects bundle size:
- RJSF — adds UI components on top of the base library
- FormEngine — completely replaces UI components during integration
Let's see how this works in practice.
Testing Methodology
We tested two realistic forms:
Login Form (Simple Case)
- Email + Password fields
- Basic validation
- Submit button
Booking Form (Complex Case)
- Multi-step form
- Conditional logic
- Different field types (text, dates, selects)
- Validation at each step
Test Conditions:
- Production build (minified + gzipped)
- Vite as bundler
- Tree-shaking enabled
- Default configurations
- Two variants: with default UI (FormEngine Core has no default UI, React Suite v5 was used) and with Material UI
Full methodology: formengine.io/documentation/bundle-size-comparison
Results (gzip sizes)
Login Form — Default UI
RJSF wins in its pure form. Bootstrap CSS is lighter than React Suite.
Login Form — With Material UI
Difference: 43 KB in favor of FormEngine
The picture changes! FormEngine becomes lighter when replacing React Suite with MUI.
Booking Form — Default UI
RJSF is ahead again. But the difference has grown — complex forms require more components.
Booking Form — With Material UI
Difference: 35 KB in favor of FormEngine
FormEngine is lighter again after MUI integration.
Key Insight: How UI Kit Changes Everything
Here's what happens when switching from default UI to Material UI:
| Form | FormEngine | RJSF |
|---|---|---|
| Login | -55.6 KB (-23%) | +56.4 KB (+32%) |
| Booking | -117.4 KB (-37%) | +56.4 KB (+32%) |
Why Does FormEngine Become Lighter?
Comparison of Different UI Library Usage:
FormEngine + React Suite by default:
├── Core engine (~50 KB)
├── React Suite components (~190 KB)
├── React Suite CSS (~52 KB)
= 244 KB total
FormEngine + MUI:
├── Core engine (~50 KB)
├── MUI components (already in project)
├── Minimal CSS (~0.2 KB)
= 188 KB total (-23%)
Why Does RJSF Become Heavier?
Additive Architecture:
RJSF by default:
├── Core engine (~156 KB)
├── Bootstrap CSS (~19 KB)
= 175 KB total
RJSF + MUI:
├── Core engine (~156 KB)
├── MUI adapter layer (~20 KB)
├── MUI components (already in project)
├── Minimal CSS (~0.2 KB)
= 232 KB total (+32%)
MUI is added on top, not replacing the base components.
What Does This Mean for Real Users?
A difference of 35–43 KB might seem small, but let's translate it into seconds:
On Slow 3G (Emerging Markets)
| Metric | 43 KB Difference | Impact |
|---|---|---|
| Load | ~1.2 sec | Slower UI appearance |
| TTI | ~1.0 sec | Slower interactivity |
On 4G (Typical Conditions)
| Metric | 43 KB Difference | Impact |
|---|---|---|
| Load | ~0.13 sec | Almost imperceptible |
| TTI | ~0.15 sec | Barely noticeable |
Conclusion: If you have users on slow networks (emerging markets, mobile internet in subways, poor WiFi) — every second is critical.
Conclusions (And What We Learned About Our Own Product)
1. Context Is Everything
You can't say "FormEngine is better than RJSF" or vice versa. The right answer depends on your project:
Choose RJSF if:
- Need minimal baseline
- JSON Schema is your primary source of truth
- Simple forms with basic validation
Choose FormEngine if:
- Already using Material UI or another UI kit
- Need deep component customization
- Complex forms with conditional logic
2. Our Competitive Advantage Is Integration
We initially designed FormEngine for embedding into existing projects with already installed UI libraries. This architectural decision paid off:
- Minus 23–37% bundle when integrating with MUI compared to React Suite
- Complete UI replacement instead of layering
- Zero overhead for components
3. Different Approach to Describing Forms in JSON
This is one of the most important differences that affects not only DX but also bundle size:
RJSF: Separate Schemas (Data Schema + UI Schema)
// data-schema.json — describes data
{
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email"
},
"password": {
"type": "string",
"minLength": 8
}
},
"required": ["email", "password"]
}
// ui-schema.json — describes UI
{
"email": {
"ui:widget": "email",
"ui:placeholder": "Enter your email"
},
"password": {
"ui:widget": "password",
"ui:help": "Min 8 characters"
}
}
Pros of Separation:
- Standardization — JSON Schema is an open standard
- Reusability — one data schema can be used in different UIs
- Validation independent of UI — can validate on backend with the same schema
- Ecosystem — many tools for JSON Schema (generators, validators, documentation)
- Separation of concerns — logic separate from presentation
Cons of Separation:
- Synchronization — need to maintain two files in sync
- Verbosity — more code for simple forms
- Learning curve — need to know both formats
FormEngine: Unified JSON (Data + UI in One JSON)
// form.json — everything in one place
{
"components": [
{
"type": "TextField",
"key": "email",
"label": "Email",
"placeholder": "Enter your email",
"validation": {
"required": true,
"email": true
}
},
{
"type": "PasswordField",
"key": "password",
"label": "Password",
"help": "Min 8 characters",
"validation": {
"required": true,
"minLength": 8
}
}
]
}
Pros of Unification:
- Simplicity — one file, one source of truth
- Less code — no duplication of field names
- Conditional logic — easier to describe dependencies between fields
- DX — faster to write and understand
- Compactness — less boilerplate
Cons of Unification:
- No standardization — proprietary FormEngine format
- Vendor lock-in — harder to migrate to another library
- Validation only on client — can't reuse schema on backend directly
- Fewer tools — no JSON Schema ecosystem
- UI and data coupling — UI changes can affect logic
Impact on Bundle Size
RJSF (separate schemas):
✦ JSON Schema validator (~15-20 KB)
✦ Standard ajv (might already be in project)
✦ UI Schema parser (~5 KB)
✦ Mapping layer between schemas (~3-5 KB)
Total: ~23-30 KB overhead
FormEngine (unified schema): ✦ Custom validator (~8-12 KB) ✦ Less parsing ✦ No ajv reuse ✦ Proprietary format Total: ~8-12 KB overhead
Conclusion: FormEngine saves ~10–15 KB on schema parsing, but loses standardization benefits.
Important note: Although FormEngine uses a proprietary format, it is fully open and documented. This means you can study the specification, write your own parsers or form generators, without depending on closed solutions.
Real Example: Complex Conditional Logic
Imagine a form where the "Phone" field is shown only if "Contact by phone" is selected:
RJSF Approach
// data-schema.json
{
"type": "object",
"properties": {
"contactMethod": {
"type": "string",
"enum": ["email", "phone"]
},
"phone": {
"type": "string",
"pattern": "^[0-9]{10}$"
}
},
"dependencies": {
"phone": ["contactMethod"]
},
"if": {
"properties": {
"contactMethod": { "const": "phone" }
}
},
"then": {
"required": ["phone"]
}
}
// ui-schema.json
{
"phone": {
"ui:widget": "phone",
"ui:options": {
"conditional": {
"show": {
"field": "contactMethod",
"is": "phone"
}
}
}
}
}
Problem: The condition is described in two places! Data schema says "phone required if...", UI schema says "show phone if...". Need to synchronize.
FormEngine Approach
{
"components": [
{
"type": "RadioGroup",
"key": "contactMethod",
"label": "Contact method",
"options": [
{ "value": "email", "label": "Email" },
{ "value": "phone", "label": "Phone" }
]
},
{
"type": "PhoneField",
"key": "phone",
"label": "Phone number",
"conditional": {
"show": "{{contactMethod === 'phone'}}"
},
"validation": {
"required": "{{contactMethod === 'phone'}}",
"pattern": "^[0-9]{10}$"
}
}
]
}
Advantage: Condition described once. UI and validation automatically synchronized.
When Is Each Approach Better?
Choose RJSF (separate schemas) if:
- You already have JSON Schema for API validation
- Need one schema for frontend and backend
- Working in a team where backend generates schemas
- Using JSON Schema ecosystem tools
- Need compatibility with third-party systems
- Simple forms without complex conditional logic
Choose FormEngine (unified schema) if:
- Forms are complex with many conditions
- UI logic is more important than data validation
- Want to avoid duplication
- DX and development speed are priorities
- Not planning to migrate to another library
4. Transparency Builds Trust
We've published all data, including scenarios where RJSF is faster. This is our principle: honesty is more important than marketing.
If you find errors in the tests — open an issue, we'll fix it.
Detailed Data
Comparison Table (All Scenarios)
| Scenario | RJSF (gzip) | FormEngine (gzip) | Winner |
|---|---|---|---|
| Login default UI | 175.26 KB | 244.19 KB | RJSF (-39%) |
| Login MUI | 231.62 KB | 188.54 KB | FormEngine (-19%) |
| Booking default UI | 178.07 KB | 316.69 KB | RJSF (-78%) |
| Booking MUI | 234.50 KB | 199.26 KB | FormEngine (-15%) |
Detailed Bundle Breakdown
RJSF Login (default UI)
Code: 480.72 KB raw / 156.37 KB gzip (80%) CSS: 117.18 KB raw / 19.27 KB gzip (20%) Total: 597.91 KB raw / 175.64 KB gzip Chunks: 2
FormEngine Login (default UI)
Code: 626.23 KB raw / 192.65 KB gzip (59%) CSS: 438.18 KB raw / 52.42 KB gzip (41%) Total: 1.04 MB raw / 245.07 KB gzip Chunks: 2
RJSF Login (MUI)
Code: 725.19 KB raw / 232.47 KB gzip (100%) CSS: 186 B raw / 169 B gzip (0%) Total: 725.37 KB raw / 232.64 KB gzip Chunks: 2
FormEngine Login (MUI)
Code: 622.22 KB raw / 189.27 KB gzip (100%) CSS: 186 B raw / 169 B gzip (0%) Total: 622.40 KB raw / 189.44 KB gzip Chunks: 2
Observation: After switching to MUI, CSS practically disappears for both libraries (186 bytes). The entire difference is in the JS code.
Practical Recommendations
If You DON'T Have a UI Library
Recommendation: RJSF
- Lighter out of the box (175 KB vs 244 KB)
- Faster setup
- No need to choose UI kit
If You HAVE Material UI
Recommendation: FormEngine
- Lighter with MUI (188 KB vs 232 KB)
- No duplication of UI code
- Full integration with your Design System
If You Have Another UI Kit
Recommendation: Depends on adapter availability
- RJSF: Has adapters for many UI kits
- FormEngine: Currently only MUI and React Suite
- Check documentation for both libraries
If Planning to Change UI Kit
Recommendation: FormEngine
- UI replacement architecture
- Easier to migrate between UI kits
- Less technical debt
Reproducibility
All tests are available and reproducible:
GitHub Repository: github.com/optimajet/formengine/tree/master/community/examples/bundle-size
Full Report: formengine.io/documentation/bundle-size-comparison
How to Run Yourself:
git clone https://github.com/optimajet/formengine.git
cd formengine/community/examples/bundle-size
npm install
npm run build
npm run analyze
What You'll Get:
- Bundle size report
- Chunk visualization
- Duplicate packages detection
- Tree-shaking analysis
What's Next?
Try It Yourself
RJSF
FormEngine
Give Feedback
If you found errors in tests, want to add new scenarios, or disagree with conclusions — write to us:
Final Verdict
There's no universal winner. And that's good!
- RJSF — excellent choice for quick start and JSON Schema purists
- FormEngine — optimal for integration into existing projects with UI kits
Choose based on your context, not marketing.
P.S. We're Optimajet, also making Workflow Engine for processes and Workflow Server for business automation.