Docs
v1.3.14
GitHubSite
Getting started / Project structure

Project structure

How FieldCraft is organised, what each package does, and how to structure schemas, components and adapters in your own project.

Package architecture

FieldCraft is a monorepo with strict dependency boundaries. Each package depends only on the one beneath it.

@squaredr/fieldcraft-core         Zero UI dependencies. Pure TypeScript.

@squaredr/fieldcraft-react        Depends on core. React + shadcn + Tailwind.

@squaredr/fieldcraft-pro          Depends on core + react. Commercial licence.

@squaredr/fieldcraft-adapters     Depends on core types only. No React.
@squaredr/fieldcraft-templates-free   Depends on core types only. No React.
PackageWhat it containsSize
fieldcraft-coreSchema types, engine factory (createEngine), state manager, condition evaluator, validation runner, expression parser, draft manager, prefill resolver, schema validator~15 KB min
fieldcraft-react<FormRenderer />, 44 field components, 4 hooks, 6 theme presets, field registry, UI primitives (shadcn/Radix)~45 KB min
fieldcraft-adaptersHTTP adapter, Supabase adapter, Postgres adapter, webhook adapter. Each with encryption, retry logic~8 KB min
fieldcraft-templates-free16 production-ready form schemas across 7 categories~12 KB min
fieldcraft-proVisual builder, schema editor, theme editor, response viewer (coming soon)Commercial
your-app/
├── schemas/                     # Form schemas (JSON or TypeScript)
│   ├── contact-form.ts
│   ├── patient-intake.ts
│   └── employee-survey.json
├── components/
│   └── forms/
│       ├── custom-fields/       # Custom field type components
│       │   ├── PainScaleField.tsx
│       │   └── ColorPickerField.tsx
│       └── FormPage.tsx         # Wrapper component
├── lib/
│   ├── adapters.ts              # Adapter configuration
│   ├── validators.ts            # Custom validators
│   └── form-registry.ts         # Custom field registry
└── app/
    └── forms/
        └── [id]/
            └── page.tsx         # Dynamic form route

Schema files

Schemas can be TypeScript files (with type checking) or JSON files (for schemas stored in a database or CMS).

TypeScript — recommended for static schemas:

import type { FormEngineSchema } from '@squaredr/fieldcraft-react'

export const contactFormSchema: FormEngineSchema = {
  id: 'contact-form',
  version: '1.0.0',
  // ... full schema
}

JSON — for dynamic schemas loaded from an API:

{
  "id": "contact-form",
  "version": "1.0.0",
  "title": "Contact Us",
  "sections": []
}

The engine accepts both formats. TypeScript gives you autocomplete and compile-time validation. JSON is useful when schemas are managed through the Pro visual builder or stored in a database.

Adapter setup

Keep adapter configuration in a dedicated file:

import { createHttpAdapter } from '@squaredr/fieldcraft-core'
import { createSupabaseAdapter } from '@squaredr/fieldcraft-adapters'
import { supabase } from './supabase'

export const httpAdapter = createHttpAdapter({
  url: '/api/submissions',
  method: 'POST',
  headers: { 'X-API-Key': process.env.NEXT_PUBLIC_API_KEY! },
})

export const supabaseAdapter = createSupabaseAdapter({
  client: supabase,
  table: 'form_submissions',
})

Then pass adapters to the renderer:

<FormRenderer
  schema={schema}
  adapters={[httpAdapter, supabaseAdapter]}
/>

Multiple adapters run in parallel — if one fails, the others still execute. Each adapter reports its own success/failure in the SubmitResult.

Custom field registry

If you have custom field types, create a registry file:

import { defaultRegistry } from '@squaredr/fieldcraft-react'
import { PainScaleField } from '@/components/forms/custom-fields/PainScaleField'
import { ColorPickerField } from '@/components/forms/custom-fields/ColorPickerField'

export const registry = {
  ...defaultRegistry,
  pain_scale: PainScaleField,
  color_picker: ColorPickerField,
}

Then pass it to the renderer:

<FormRenderer
  schema={schema}
  components={registry}
/>

Next steps

On this page