Form.io’s drag and drop form builder is not a tool for making pretty forms. It is a JSON schema generator that simultaneously defines form UI, validation rules, the data model, and REST API endpoints. When you drag a text field onto the canvas, you are not drawing a rectangle on a webpage. You are writing a line of JSON that tells Form.io’s renderer how to display the field, what validation to apply, and what shape the submission data should take.
This distinction matters because it determines what kind of applications you can build. Most form builders output HTML or embed an iframe. Form.io outputs a schema that your application consumes at runtime. The form never exists as static markup. It is rendered dynamically by a JavaScript library that interprets the JSON and constructs the DOM.
The Form Builder Is a Schema Editor
Every field in Form.io’s builder corresponds to a JSON object. When you configure a text field’s label, placeholder, required validation, and conditional visibility, you are populating properties on that object. The builder’s sidebar is a visual interface for editing JSON.
Here is what a simple two-field form looks like as JSON:
{
"components": [
{
"type": "textfield",
"key": "firstName",
"label": "First Name",
"placeholder": "Enter your first name",
"validate": { "required": true }
},
{
"type": "textfield",
"key": "lastName",
"label": "Last Name"
},
{
"type": "button",
"action": "submit",
"label": "Submit"
}
]
}
This schema is what Form.io’s JavaScript renderer consumes to build the form on the page. The same schema also defines the API endpoints that accept submissions. There is no separate backend configuration step. The schema is the single source of truth for both frontend and backend.
You can see this relationship in real-time using the Form Builder Demo. As you add and configure components, the JSON updates live. This makes it clear that the visual builder is not abstracting away complexity. It is surfacing it in a way that non-developers can manipulate without breaking the underlying schema.
What the Builder Does Not Do
The form builder creates schemas and submissions. It does not create application logic, page layouts, navigation, or user authentication flows. Form.io is forms as infrastructure, not an application framework.
If you need:
- Multi-page application routing, you build that in your Angular, React, or Vue application
- Custom business logic beyond validation, you write that in your application code or use Form Actions and webhooks
- User interface components outside of forms, you build those yourself
This is a deliberate constraint. Form.io is an OEM form runtime designed to be embedded in applications that developers control. The builder creates the forms. Your application creates everything else.
Form Schemas vs Submission Schemas
A common source of confusion is the difference between a form’s schema and the submissions it collects. The form schema describes the structure of the form: what components it contains, how they are labeled, what validation rules apply. The submission schema describes the data that users enter.
For the form above, a submission would look like:
{
"data": {
"firstName": "Jane",
"lastName": "Smith"
}
}
The key property on each component determines the property name in the submission. This is why Form.io requires unique keys across components. Duplicate keys would produce ambiguous submission data.
Understanding this distinction is essential for working with Form.io’s API. The /form endpoint returns form schemas. The /submission endpoint returns submission data. They are different data structures with different access patterns. For a deeper treatment of this relationship, see Form Schemas vs Submissions [/features/form-schemas-vs-submissions].
Embedding the Builder in Your Application
The form builder is not limited to Form.io’s portal interface. It is a JavaScript library that you can embed in your own application. This allows you to expose form building capabilities to your end users without giving them access to the Form.io portal.
<div id="builder"></div>
<script src="https://cdn.form.io/js/formio.full.min.js"></script>
<script>
Formio.builder(document.getElementById('builder'), {}, {})
.then(function(builder) {
builder.on('saveComponent', function() {
console.log(builder.schema);
});
});
</script>
The Formio.builder method returns a promise that resolves with the builder instance. You can listen for events like addComponent, removeComponent, and updateComponent to respond to user actions. The builder’s schema property always contains the current form definition.
This is how multi-tenancy works in practice. Your SaaS customers can build forms using a builder you embed in your application. Those forms are stored in Form.io’s project hierarchy and isolated from other tenants. But the interface your customers see is yours, styled with your CSS, integrated into your navigation, controlled by your permissions system.
Customizing the Builder Sidebar
The default builder sidebar contains component categories like Basic, Advanced, Layout, and Data. You can customize which components appear and add pre-defined component configurations.
For example, if your application only needs text fields, email fields, and select dropdowns, you can configure the builder to show only those:
Formio.builder(document.getElementById('builder'), {}, {
builder: {
basic: {
title: 'Form Fields',
components: {
textfield: true,
email: true,
select: true
}
},
advanced: false,
layout: false,
data: false,
premium: false
}
});
You can also define pre-configured fields. Instead of dragging a generic text field and configuring it as “First Name,” you can provide a First Name field that comes pre-configured:
Formio.builder(document.getElementById('builder'), {}, {
builder: {
custom: {
title: 'User Fields',
components: {
firstName: {
title: 'First Name',
key: 'firstName',
schema: {
type: 'textfield',
key: 'firstName',
label: 'First Name',
validate: { required: true }
}
}
}
}
}
});
This is documented in detail in the Form Builder SDK documentation.
Why the Builder Matters for Backend API Generation
When you save a form in Form.io, the platform does not just store the JSON. It registers API endpoints for that form. A form at path /user/registration automatically gets:
POST /user/registration/submissionto create new submissionsGET /user/registration/submissionto list submissionsGET /user/registration/submission/:idto retrieve a specific submissionPUT /user/registration/submission/:idto update a submissionDELETE /user/registration/submission/:idto delete a submission
The backend API is the set of endpoints that accept form submissions and return form data. Form.io generates these endpoints automatically from the form schema.
The API enforces the validation rules defined in the schema. If you mark a field as required, the API will reject submissions that omit it. If you set a maximum length, the API will reject submissions that exceed it. Frontend validation and backend validation use the same schema.
This is a key difference from building forms with HTML and writing validation logic separately for the frontend and backend. With Form.io, validation is defined once and enforced everywhere.
When the Builder Is Not Enough
The drag and drop builder handles common form patterns well. Text fields, select dropdowns, date pickers, file uploads, conditional visibility, calculated values. But some requirements exceed what the builder can express visually.
For those cases, Form.io provides escape hatches:
Custom components: You can register your own component types with the renderer. These appear in the builder like native components but render and behave according to your code. See the Custom Components documentation.
Raw JSON editing: Every component in the builder has an Edit JSON button that opens the raw schema. You can modify properties that the visual interface does not expose.
Form evaluations: You can write JavaScript expressions that run during form rendering, validation, or submission. These are documented in Form Evaluations.
These are power-user features. Most forms do not need them. But they exist because Form.io is designed to handle complex enterprise requirements, not just simple contact forms.
The Renderer Is Separate from the Builder
It is important to understand that form building and form rendering are different concerns handled by different parts of the Form.io stack.
The builder is for creating and editing form schemas. It runs in the Form.io portal or in your embedded builder interface. It produces JSON.
The renderer is for displaying forms to end users and collecting submissions. It runs in your application. It consumes JSON and produces a DOM.Both use the same underlying formio.js library, but they invoke different methods:
// Builder
Formio.builder(element, schema, options);
// Renderer
Formio.createForm(element, 'https://yourproject.form.io/yourform');
The renderer can also accept raw JSON instead of a Form.io URL:
Formio.createForm(element, {
components: [
{ type: 'textfield', key: 'name', label: 'Name' }
]
});
This separation means you can use the builder to create forms and export them as JSON files. You could then render those forms without any connection to Form.io’s servers. The renderer is open source. The builder is open source. You could, in theory, run the entire system self-hosted. This is documented in the deployment guide.
What Form.io Is Not
Form.io is not a low-code platform for building complete applications. It is not a Retool or Appsmith competitor. It is schema-driven data capture for bespoke applications.
Form.io is not a Google Forms replacement. Google Forms is a standalone product for simple surveys. Form.io is infrastructure that developers embed in their own applications.
Form.io is not a PDF forms replacement, although it can output submissions to PDF and can render fillable PDF forms.
If you are looking for a tool that lets non-technical users build complete business applications without a development team, Form.io is not that tool. See Why You Should Not Use Form.io If You Do Not Have a Dev Team.
If you are a developer building a form-intensive application and you want to stop writing form rendering logic, validation logic, and submission handling code for every form, Form.io is forms + APIs, not forms + UI.
Related Documentation
- Form Renderer Documentation
- Form Builder Documentation
- Form Building User Guide
- Form JSON Schema Reference
- JavaScript SDK on GitHub
- API Documentation
Related Features
- JSON-Driven Forms: How the schema-first architecture works
- Form Validation & Conditional Logic: Defining rules in the builder
- Premium and Custom Form Components: Extending the component library
- Multi-Tenancy: Embedding the builder for your SaaS customers
- Decoupled Form Updates: How schema changes propagate to rendered forms
