FieldCraftPayKitDocsServicesBlogWork With Me →
Back to Blog

Introducing FieldCraft: A Schema-Driven Form Engine for React

The Problem

Every React project eventually needs forms. And every team eventually builds the same infrastructure: validation, error display, conditional fields, multi-step flows, draft saving, theming.

You wire up state. You add validation. You handle edge cases. You realize the contact form and the onboarding flow share 80% of the same plumbing. You refactor. You add more forms. The plumbing grows.

FieldCraft exists so you never write that plumbing again.

What It Is

FieldCraft is a schema-driven form engine. You define your form as a JSON schema — fields, validation rules, conditional logic, sections — and the engine handles everything else.

import { FormEngineRenderer } from '@squaredr/fieldcraft-react'
import '@squaredr/fieldcraft-react/styles.css'

const schema = {
id: 'contact',
title: 'Contact Us',
fields: [
{
id: 'name',
type: 'text',
label: 'Your Name',
required: true,
},
{
id: 'email',
type: 'email',
label: 'Email Address',
required: true,
},
{
id: 'type',
type: 'select',
label: 'Inquiry Type',
options: [
{ label: 'General', value: 'general' },
{ label: 'Support', value: 'support' },
{ label: 'Enterprise', value: 'enterprise' },
],
},
{
id: 'message',
type: 'textarea',
label: 'Message',
required: true,
validation: { minLength: 10 },
},
],
}

export default function ContactPage() {
return (
<FormEngineRenderer
schema={schema}
onSubmit={(response) => console.log(response.values)}
/>
)
}

That's a working form with validation, error messages, and keyboard navigation. No useState, no onChange handlers, no validation library.

What You Get

35+ Field Types

Text, email, number, phone, select, multi-select, checkbox, radio, toggle, rating, slider, date, time, file upload, signature pad, and more. Each field type handles its own rendering, validation, and accessibility.

Conditional Logic

Show or hide fields based on other field values. Supports nested AND/OR condition groups.

{
"id": "company",
"type": "text",
"label": "Company Name",
"showIf": {
"field": "type",
"operator": "equals",
"value": "enterprise"
}
}

The "Company Name" field only appears when the user selects "Enterprise" as their inquiry type. The engine re-evaluates conditions on every change, handles visibility cascading, and cleans up hidden field values.

Multi-Step Sections

Split long forms into steps. The engine tracks progress, validates per-section, and lets users navigate back without losing data.

{
"sections": [
{
"id": "basics",
"title": "Basic Info",
"fields": ["name", "email"]
},
{
"id": "details",
"title": "Details",
"fields": ["type", "message"]
}
]
}

Validation

Required fields, min/max length, regex patterns, numeric ranges, custom validators. Errors show on blur by default — not on every keystroke.

Computed Fields

Fields that calculate their value from other fields using an expression engine.

{
"id": "total",
"type": "computed",
"expression": "quantity * price"
}

Draft Persistence

Long forms auto-save to localStorage. If a user closes the tab and comes back within 72 hours, their progress is restored. No configuration needed — it's on by default.

Theming

Six built-in theme presets: Clean, Dark, Modern, High Contrast, Clinical, and Playful. Or pass your own theme object for full control over colors, spacing, border radius, and typography.

<FormEngineRenderer
schema={schema}
theme="dark"
onSubmit={handleSubmit}
/>

Custom Field Types

Need a field type that doesn't exist? Register your own through the field registry.

Storage Adapters

Form data needs to go somewhere. FieldCraft ships three storage adapters — all MIT licensed:

  • Postgres (@squaredr/fieldcraft-postgres) — Built on Drizzle ORM with optional field-level AES-256-GCM encryption
  • Supabase (@squaredr/fieldcraft-supabase) — Works with existing Supabase projects
  • Webhook (@squaredr/fieldcraft-webhook) — POST to any endpoint with HMAC-SHA256 signed payloads

You pick which fields get encrypted. An email field can be encrypted while a "how did you hear about us" field stays queryable in plain text.

Why Schema-Driven

Writing forms imperatively (JSX + state + validation per field) works fine for one or two forms. It stops working when you have 10 forms, or when non-developers need to create forms, or when the same form needs to render on multiple platforms.

A JSON schema is portable. It can be stored in a database, generated by a form builder, or shared between a React frontend and a React Native app. The schema is the source of truth — the renderer is interchangeable.

FieldCraft's core engine (@squaredr/fieldcraft-core) is renderer-agnostic. The React renderer (@squaredr/fieldcraft-react) is one implementation. The schema format stays the same regardless of how you render it.

Get Started

npm install @squaredr/fieldcraft-core @squaredr/fieldcraft-react

Full documentation, live examples, and API reference at squaredr.tech/products/fieldcraft/docs.

All packages are MIT licensed. 314 passing tests. Full TypeScript support.

Check the roadmap to see what's shipping next — and submit feature requests directly from the page.