Skip to main content

Quickstart

Get started with JSON Forms in minutes. This guide will walk you through creating your first form from installation to a working example.

What you’ll build

A simple task management form with:
  • Text input for task name
  • Checkbox for completion status
  • Date picker for due date
  • Dropdown for recurrence options

Prerequisites

  • Node.js 22+ installed
  • Basic knowledge of React, Angular, or Vue
  • A package manager (npm, yarn, or pnpm)

React Setup

1

Install dependencies

Install JSON Forms Core, React bindings, and Material renderers:
npm install @jsonforms/core @jsonforms/react @jsonforms/material-renderers
Install Material-UI peer dependencies:
npm install @mui/material @mui/icons-material @emotion/react @emotion/styled @mui/x-date-pickers
2

Create your JSON Schema

Define the structure and validation rules for your data:
const schema = {
  type: 'object',
  properties: {
    name: {
      type: 'string',
      minLength: 1,
    },
    done: {
      type: 'boolean',
    },
    due_date: {
      type: 'string',
      format: 'date',
    },
    recurrence: {
      type: 'string',
      enum: ['Never', 'Daily', 'Weekly', 'Monthly'],
    },
  },
  required: ['name', 'due_date'],
};
The schema uses JSON Schema standard. The type defines data types, minLength adds validation, and required marks mandatory fields.
3

Create your UI Schema (optional)

Customize the layout of your form:
const uischema = {
  type: 'VerticalLayout',
  elements: [
    {
      type: 'Control',
      label: false,
      scope: '#/properties/done',
    },
    {
      type: 'Control',
      scope: '#/properties/name',
    },
    {
      type: 'HorizontalLayout',
      elements: [
        {
          type: 'Control',
          scope: '#/properties/due_date',
        },
        {
          type: 'Control',
          scope: '#/properties/recurrence',
        },
      ],
    },
  ],
};
The UI Schema is optional. Without it, JSON Forms will automatically generate a layout based on your JSON Schema.
4

Render the form

Create your component using the JsonForms component:
App.tsx
import React, { useState } from 'react';
import {
  materialRenderers,
  materialCells,
} from '@jsonforms/material-renderers';
import { JsonForms } from '@jsonforms/react';

const schema = {
  type: 'object',
  properties: {
    name: {
      type: 'string',
      minLength: 1,
    },
    done: {
      type: 'boolean',
    },
    due_date: {
      type: 'string',
      format: 'date',
    },
    recurrence: {
      type: 'string',
      enum: ['Never', 'Daily', 'Weekly', 'Monthly'],
    },
  },
  required: ['name', 'due_date'],
};

const uischema = {
  type: 'VerticalLayout',
  elements: [
    {
      type: 'Control',
      label: false,
      scope: '#/properties/done',
    },
    {
      type: 'Control',
      scope: '#/properties/name',
    },
    {
      type: 'HorizontalLayout',
      elements: [
        {
          type: 'Control',
          scope: '#/properties/due_date',
        },
        {
          type: 'Control',
          scope: '#/properties/recurrence',
        },
      ],
    },
  ],
};

const initialData = {};

function App() {
  const [data, setData] = useState(initialData);
  
  return (
    <JsonForms
      schema={schema}
      uischema={uischema}
      data={data}
      renderers={materialRenderers}
      cells={materialCells}
      onChange={({ data, _errors }) => setData(data)}
    />
  );
}

export default App;
5

Run your application

Start your development server and view your form:
npm start
You should see a form with all the fields defined in your schema, styled with Material-UI components.

Understanding the code

The JsonForms component requires:
  • schema - Defines the data structure and validation
  • uischema - (Optional) Customizes the form layout
  • data - Current form data
  • renderers - Set of UI components to render controls
  • cells - Table cell renderers for array layouts
  • onChange - Callback when data changes
import React, { useState } from 'react';
import {
  materialRenderers,
  materialCells,
} from '@jsonforms/material-renderers';
import { JsonForms } from '@jsonforms/react';

const schema = {
  type: 'object',
  properties: {
    name: {
      type: 'string',
      minLength: 1,
    },
    done: {
      type: 'boolean',
    },
    due_date: {
      type: 'string',
      format: 'date',
    },
    recurrence: {
      type: 'string',
      enum: ['Never', 'Daily', 'Weekly', 'Monthly'],
    },
  },
  required: ['name', 'due_date'],
};

const uischema = {
  type: 'VerticalLayout',
  elements: [
    {
      type: 'Control',
      label: false,
      scope: '#/properties/done',
    },
    {
      type: 'Control',
      scope: '#/properties/name',
    },
    {
      type: 'HorizontalLayout',
      elements: [
        {
          type: 'Control',
          scope: '#/properties/due_date',
        },
        {
          type: 'Control',
          scope: '#/properties/recurrence',
        },
      ],
    },
  ],
};

const initialData = {};

function App() {
  const [data, setData] = useState(initialData);
  
  return (
    <div style={{ padding: '2rem' }}>
      <h1>Task Manager</h1>
      <JsonForms
        schema={schema}
        uischema={uischema}
        data={data}
        renderers={materialRenderers}
        cells={materialCells}
        onChange={({ data, _errors }) => setData(data)}
      />
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}

export default App;

Understanding the schemas

JSON Schema

The JSON Schema defines your data model:
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",        // Field type
      "minLength": 1           // Validation rule
    },
    "done": {
      "type": "boolean"
    },
    "due_date": {
      "type": "string",
      "format": "date"         // Special format
    },
    "recurrence": {
      "type": "string",
      "enum": ["Never", "Daily", "Weekly", "Monthly"]  // Dropdown options
    }
  },
  "required": ["name", "due_date"]  // Required fields
}
Common field types:
  • string - Text input
  • number / integer - Numeric input
  • boolean - Checkbox
  • array - List of items
  • object - Nested object
Common formats:
  • date - Date picker
  • time - Time picker
  • date-time - Date and time picker
  • email - Email input with validation
  • uri - URL input

UI Schema

The UI Schema controls layout and appearance:
{
  "type": "VerticalLayout",      // Stack elements vertically
  "elements": [
    {
      "type": "Control",         // Single form control
      "scope": "#/properties/name",  // References JSON Schema property
      "label": "Task Name"       // Optional custom label
    },
    {
      "type": "HorizontalLayout",  // Stack elements horizontally
      "elements": [
        {
          "type": "Control",
          "scope": "#/properties/due_date"
        },
        {
          "type": "Control",
          "scope": "#/properties/recurrence"
        }
      ]
    }
  ]
}
Available layout types:
  • VerticalLayout - Stack elements vertically
  • HorizontalLayout - Stack elements horizontally
  • Group - Grouped section with optional label
  • Categorization - Tabbed interface

Next steps

Congratulations! You’ve created your first JSON Form. Here’s what to explore next:

Core Concepts

Learn about JSON Schema, UI Schema, and renderers

Custom Renderers

Create custom form controls for specific needs

Validation

Add custom validation rules and error messages

Examples

Explore more complex form examples

Common patterns

Handling form submission

function App() {
  const [data, setData] = useState({});
  
  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    console.log('Form data:', data);
    // Send to API, validate, etc.
  };
  
  return (
    <form onSubmit={handleSubmit}>
      <JsonForms
        schema={schema}
        uischema={uischema}
        data={data}
        renderers={materialRenderers}
        cells={materialCells}
        onChange={({ data }) => setData(data)}
      />
      <button type="submit">Submit</button>
    </form>
  );
}

Accessing validation errors

function App() {
  const [data, setData] = useState({});
  const [errors, setErrors] = useState([]);
  
  return (
    <JsonForms
      schema={schema}
      uischema={uischema}
      data={data}
      renderers={materialRenderers}
      cells={materialCells}
      onChange={({ data, errors }) => {
        setData(data);
        setErrors(errors || []);
      }}
    />
  );
}

Pre-filling form data

const initialData = {
  name: 'My Task',
  done: false,
  due_date: '2024-12-31',
  recurrence: 'Daily'
};

function App() {
  const [data, setData] = useState(initialData);
  // ... rest of component
}

Troubleshooting

Make sure you’ve installed all peer dependencies for your chosen renderer set. Check the installation guide for the complete list.
JSON Forms uses AJV for validation. Ensure your JSON Schema is valid and uses standard JSON Schema keywords. Custom formats may require additional AJV configuration.
Ensure all JSON Forms packages are using the same version. Mismatched versions can cause type conflicts.
Make sure you’ve imported the required styles and configured the theme provider for your UI library (Material-UI, Vuetify, etc.).

Get help

If you encounter issues or have questions:

Build docs developers (and LLMs) love