DEV Community

Cover image for Forms at Scale Are Not Just UI—They’re Architecture
yanggmtl
yanggmtl

Posted on • Edited on

Forms at Scale Are Not Just UI—They’re Architecture

I used to think forms were just UI. You open a React component, add inputs, wire validation, and ship it. This works—until you scale.

When your product needs conditional fields, multi-tenant validation, or backend-driven workflows, "Just UI" breaks. Here is the architectural shift I took to solve this.

1. The Realization: Forms are Data, Not Screens

If a form is hardcoded in React, its definition is trapped. It’s coupled to deployment cycles and framework-specific logic.

The Shift: I moved to Schema-Driven Forms.
React stopped being the author and became the renderer. This made forms portable and dynamic, but it introduced a new problem: Schema Bloat.

2. The Trap: The "Mini-Programming Language" Schema

As requirements grew, my schemas started absorbing logic (if/then visibility, complex validation). The schema stopped being data and became a messy, hard-to-debug configuration layer.

I realized I was asking the wrong question. It wasn't about making forms dynamic; it was about Separation of Concerns.

3. The Breakthrough: The Registry Pattern

To keep the schema clean, I stopped implementing logic inside it. Instead, I used Registries.

  • The Schema: Only references behavior (e.g., "visibilityRef": "isAdmin").
  • The Registry: Implements the actual code logic.
// The logic lives in code, not the JSON
const adminOnly = (values) => values.role === 'admin';
registerVisibility('isAdmin', adminOnly);
Enter fullscreen mode Exit fullscreen mode

4. The Architecture: Meet the Runtime

Once definition and behavior were separated, I needed an engine to orchestrate them. This is the "Brain" of the system.
The Three-Layer Model

  • Definition (JSON): The blueprint. No executable logic.

  • Runtime (The Engine): Manages state, evaluates registry rules, and triggers validation.

  • Renderer (UI): A thin layer (React, Vue, or Angular) that simply reflects the Runtime's state.

Why This Matters

By treating forms as architecture rather than UI:

  • Framework Agnostic: The core logic (Runtime) is stable across React, Vue, Angular and Vanilla JS.

  • Decoupled Logic: You can update validation or visibility rules without touching the UI components.

  • Maintainable Scale: The "definition" stays human-readable, while the "complexity" is modularized in the registry.

This philosophy is why I built Formitiva. It’s not just a library; it’s an honest separation of what a form is, how it acts, and how it looks.

Formitiva is a schema-driven form runtime engine built for teams that need forms to behave like portable system data, not hand-wired component trees. Describe intent in JSON, let the runtime handle execution, and keep renderers replaceable.

Now Formitiva supports 4 frameworks: React, Vue, Angular and Vanilla JS.

GitHub Link: https://github.com/Formitiva/formitiva-monorepo

Top comments (0)