This demo project showcases a type-safe templating system for React applications that is configurable via JSON.
The configuration is defined by JSON schemas, declared alongside the template React components.
Types are extracted directly from these schemas to ensure 100% type safety.
The configuration is editable inside the React app via a form and a JSON editor page.
The form is autogenerated from the JSON schema.
The JSON editor is Monaco, the VSC backend, and offers IntelliSense and validation backed by the JSON schema.
Configurable dashboard PoC displaying dynamic components
Code snippet demonstrating the declaration of a component and its JSON-schema based configuration.
In-browser app configuration via JSON editor, featuring IntelliSense support provided by the JSON schema, and a Diff view for comparing configurations
In-browser app configuration via forms, automatically generated from the JSON schema for easy configuration adjustments
If you’re building a React application with a variety of complex, configurable features, this template helps by enabling a 100% type-safe templating.
- React: uses
create-react-app
+react-router-dom
just for demo purposes. - MUI: Supplies fundamental UI components and charts.
- TypeScript: Ensures type safety across components.
- TypeBox: A TypeScript library for defining JSON schemas and extracting type-safe interfaces, making "impossible configuration states impossible".
- AJV: A JSON schema validator to validate the configuration.
- react-jsonschema-form: Dynamically generates forms based on JSON schema definitions, allowing new fields and components to be added without additional code.
- Monaco Editor: Runs Visual Studio Code’s backend in the browser, providing a JSON editor with IntelliSense and diff support.
This templating system utilizes JSON schema to configure component layouts, enabling dynamic form rendering and editable configurations. Here’s a breakdown of the main components:
-
src/lib/chartComponents/*
Contains the ChartComponents available in this demo. Each ChartComponent exports:slug
: a unique identifier for the component.jsonSchema
: a schema describing the component’s configuration options.Component
: the React component itself, which receivesProps
as defined by thejsonSchema
.
-
src/lib/chartComponents/index.ts
Exports all ChartComponents in a single array. -
src/jsonSchema.ts
Provides the JSON schema setup for data validation. -
src/pages/configuration.tsx
Uses the Browser LocalStorage API to simulate a configuration repository. -
src/pages/Dashboard.tsx
Reads configuration settings and renders the appropriate components with their respective props. -
src/lib/TypeToComp.tsx
A TypeScript utility that helps track and enforce correct types for each component. -
src/pages/FormEditor.tsx
Usesrjsf
to render a form based on the JSON schema. This form is fully dynamic, meaning no additional code is required to add new fields or components.
rjsf
is a neat library that can be customized including support for custom components. See their Playground for more examples. -
src/pages/JsonEditor.tsx
Utilizes Monaco Editor to edit JSON schema with a Diff view, supporting IntelliSense based on schema declarations.
- Launch the app and change the configuration using either the Form or the JSON editor.
- Save, and the app will refresh to update the configuration.
Both the Form and JSON editor enforce validation to prevent invalid configurations from being stored. - The Dashboard will then reflect the updated configuration.
- Create a new ChartComponent in
src/lib/chartComponents/
. - Export the required keys:
Component
,jsonSchema
,slug
. - Add the new ChartComponent to the
charts
array insrc/lib/chartComponents/index.ts
.
Sure, check this commit 1fe4a03!
The following files were modified:
src/configuration.tsx
: to add a default configuration for the new component.src/lib/chartComponents/StraightAnglePieChart.tsx
: to create the new ChartComponent.src/lib/chartComponents/index.ts
: to export the new ChartComponent.
- Templating for Routing: Enable configuration at the navigation level, allowing multiple pages to be templated and the NavBar to be dynamically updated.
- Configuration Backend: including features like:
- Optimistic concurrency control to avoid overwriting changes made by others.
- Aliased configurations for easy comparison of different setups side by side.
- Complex Nesting: Support for even deeper and more nested component structures.
- RJSF UISchema and Custom Widgets: More customization options for form generation.
- Monaco Diff/Single View Switch: Enable users to toggle between views and collapse/expand JSON structures.
- Next.js Integration: Combine this setup with a framework like Next.js, including SSG/SSR support.
Yes, it’s stable and running in production environments.
We initially worried about non-engineers using the JSON editor, but it has proven safe and intuitive even for less technical users.
I'm a TDD addict. I hear you.
This system is 100% typesafe.
The only untested behavior is the configuration get/put functions, which can be tested with any of your regular Adapter testing strategies.
Buzz me on LinkedIn!