React JSON Schema Form Alternative: FormEngine vs RJSF Bundle Size Comparison

We compared two direct competitors in the JSON-based React forms space. RJSF is lighter out of the box (175 KB vs 244 KB). But if you already have Material UI, FormEngine becomes 23% lighter (188 KB), while RJSF gets 32% heavier (232 KB). Your choice of UI library determines the winner.

Disclaimer: Hi! We're the team at Optimajet, creators of FormEngine. This is an honest technical comparison of our library with react-jsonschema-form (RJSF). All tests are public, reproducible, and available on GitHub.

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

RJSF175.26 KB (baseline)
FormEngine + React Suite (v5)244.19 KB (+39%)

RJSF wins in its pure form. Bootstrap CSS is lighter than React Suite.

Login Form — With Material UI

FormEngine188.54 KB (-23% from default!)
RJSF231.62 KB (+32% from default)

Difference: 43 KB in favor of FormEngine

The picture changes! FormEngine becomes lighter when replacing React Suite with MUI.

Booking Form — Default UI

RJSF178.07 KB (baseline)
FormEngine + React Suite (v5)316.69 KB (+78%)

RJSF is ahead again. But the difference has grown — complex forms require more components.

Booking Form — With Material UI

FormEngine199.26 KB (-37% from default!)
RJSF234.50 KB (+32% from default)

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

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.