react-json-form-engine
Build lightning fast web forms from JSON.
:heart: Conditional logic
:heart: Flexible validation
:heart: Infinite depth
:heart: Rehydratable
While other libraries might utilize react-redux, or the refs
or context
API for complex form managagement, react-json-form-engine
relies on React as little as possible, and offloads its core logic to plain JavaScript. The result is scalable, lightning fast performance with neglible reliance on the React lifecycle.
Before proceeding, it's important to note that this library was designed to manage large forms (multi-section and multi-subsection), that may contain complex field dependencies (e.g Only show the Select Guardian field if the Age response is less than 18
). This may or may not be for you, but it can also handle simple forms with extreme ease.
It also offers an easy mechanism for serializing all form responses to JSON for persistence. The reverse also stands, as any form can be easily rehydrated from historical data, and returned to its previous state.
Table of Contents
Live Demo
https://mikechabot.github.io/react-json-form-engine-storybook/
Storybook repository located here
Installing
Requires React 15.0.0+
$ npm install --save react-json-form-engine
Note: This library renders Bulma semantics; you'll need to include the styles on your own for everything to look nice. You can either install it with npm, or have it served from a CDN.
Note: Font Awesome is supported.
Bulma via CDN
Bulma via npm
$ npm install --save bulma
- If your project supports Sass/SCSS, Bulma can be over easily overriden:
- Depending on your build pipeline, either import the compiled CSS, or uncompiled SCSS.
Font Awesome
If you'd like to use Font Awesome, be sure to also include the icon pack:
Starter Template
Getting Started
First, let's import the API:
Next, we'll need to build a Form Definition, which is the skeleton structure that describes how the form should look and behave. The definition must adhere to a strict schema, and can be represented as a JavaScript object or a JSON Schema. But don't worry about the details yet, we'll get into those.
Once we've built our definition, we'll feed it to the FormEngine
, which returns an instance:
Then, we just pass the instance to the <Form />
component, and react-json-form-engine
takes care of the rest:
Login Form Example
Let's create a simple login form. Either follow along below, or check out the codesandbox.
Show Title | Hide Title |
---|---|
![]() |
![]() |
Login Form Definition
Here's our definition, which is a rather simple one. It consists of just a single section with a single subsection, which houses three fields. Note, we're also using a Field Decorator to ensure user_pass
renders as a password field:
Now that we have our definition, let's create an instance of FormEngine
:
With the instance in hand, we can pass it our <Form />
component:
And once filled out, onSubmit
will get us the form responses:
Login Form Codesandbox
Have a look at the Login Form demo:
Form Engine
- Form Definition
- Field Definition
- Field Type
- Field Children
- Field Options
- Field Props List
- Field Type Transitions
- Field Decorators
Form Definition
Form definitions adhere to a strict schema. They must contain at least one section, which contains at least one subsection, which contains at least one Field Definition. You may find this schema verbose for smaller forms, however it scales well for significantly complex forms.
View the full schema in the FormAPIService
In forms with a single section, vertical tabs are not displayed. In sections with a single subsection, horizontal tabs are not displayed.
Have a look the Simple Form demo:
Form Definition Validation
Don't worry about making mistakes with your definition. If the FormEngine
is instantiated with a malformed definition, the UI will be notified of the failure location:

Have a look at the Malformed Form demo:
Field Definition
Field definitions also adhere to a strict schema. At minimum, they must contain an id
, type
and title
:
Field Type
Determines the data type of the response value stored in the model, and which Default Control to render. To override the default and render an Allowed Control instead, use a Field Decorator.
Field Type | Default Control | Allowed Controls | Supports options ? |
---|---|---|---|
string |
<Text /> |
<Password /> , <Textarea /> , <Select /> , <Radio /> |
Yes* |
boolean |
<Checkbox /> |
<Radio /> |
Yes* |
number |
<Number /> |
<Range /> |
No |
array |
<Select /> |
<Checkboxgroup /> |
Yes |
date |
<DateTime /> |
N/A | No |
Some field types will automatically transition from their Default Control to another Allowed Control if an
options
array is present in the field definition. (See Field Type Transitions). However, in most cases, you must use a
Field Decorator to use another Allowed Control.
Field Children
Any field can contain child fields. Simply create a fields
array on the field, and drop in valid Field Definitions. Here's an example of some nested fields:
Note: Field children can recurse infinitely, and also be placed on Field Options.
Have a look at the Child Fields demo:
Field Options
Applies to
string
,boolean
, andarray
field types only.
boolean
Fields of type boolean
only accept a maximum of two options; each of which should contain just a title
property. The first option is considered the affirmative response:
{
id: 'my_bool',
title: 'How often does it occur?',
type: 'boolean',
options: [
{ title: 'Always' },
{ title: 'Never' },
]
}
string
/ array
For field types that accept unlimited options (string
, array
), you must include both an id
and title
. The ids
of the selected option(s) are stored in the model.
Field Children on Options
For field controls that render selectable options, like <Radio />
(incarnated as a string
or boolean
) or <Checkboxgroup />
, you can include Field Children on any of the options:
Have a look at the Field Options demo:
Field Props List
Here's the complete list of props that can be passed to Field Definitions:
Property | Type | Required | Description |
---|---|---|---|
id |
string |
Yes | See Field ID |
type |
string |
Yes | See Field Type |
title |
string |
Yes | Display label for the field |
options |
array |
No | See Field Options |
fields |
array |
No | See Field Children |
placeholder |
string |
No | Placeholder text to display |
showCondition |
object |
No | Condition object (See Conditions) |
required |
boolean |
No | Whether the field is required (See Validation) |
pattern |
string |
No | Pattern to match during validation (See Validation) |
min |
number |
Yes* | Minimum value. (Used for number field types) |
max |
number |
Yes* | Maximum value. (Used for number field types) |
hideTime |
boolean |
No | Only show the Date in Date/Time. (Used for date field types) |
hideCalendar |
boolean |
No | Only show the Time in Data/Time. (Used for date field types) |
min
andmax
are only required for<Range />
component types.
Field Type Transitions
string
By default, a string
field is rendered as <Text />
(See Field Type), but with options
it automatically renders as a <Select />
.
Have a look at the String Transition demo:
boolean
By default, a boolean
field is rendered as <Checkbox />
(See Field Type), but with options
it automatically renders as a <Radio />
.
A maximum of two (2) options is allowed for
boolean
fields. For unlimited<Radio />
options, use thestring
type with acomponent
ofradio
.
Have a look at the Boolean Transition demo:
Field Decorators
Field decorators contain metadata about the fields you've configured in your form definition. Add the decorators
object to the root of the Form Definition:
The decorators
object will be keyed by Field ID, and can contain the properties hint
and component
.
Hint Decorator
Add hint text to any field:
Take a look at the Hint Decorator demo:
Component Decorator
Every field type
renders a Default Control (See Field Type), however you'll often want to explicitly override the default component type in favor of another. In some cases, this occurs automatically (See Field Type Transitions, however most times you'll need to specify a component decorator.
Let's update field_1
from a <Select />
to a <Checkboxgroup />
:
Here's a list of field types with overrideable components:
Field Type | Component Decorator Overrides |
---|---|
string |
password , textarea , radio |
number |
range |
array |
checkboxgroup |
Take a look a the Component Override demo: