Get Started with Atlas Forms

Install the packages, define a form schema in JSON, render it with the FormRenderer component, and handle submission — all in under 30 minutes.

Prerequisites

Node.js
Node 18+ and pnpm (monorepo uses pnpm workspaces)
React
React 18+ and TypeScript 5.0+ (strict mode)
BizFirstAi Platform
Backend API running for form definition and data storage

Installation

1
Install the core packages

Install the minimum packages needed to render a form. The types, schema, and validation packages have zero external dependencies.

pnpm add @atlas-forms/types-js pnpm add @atlas-forms/schema-js pnpm add @atlas-forms/validation-js pnpm add @atlas-forms/form-engine-js pnpm add @atlas-forms/state-react pnpm add @atlas-forms/player-components-react pnpm add @atlas-forms/controls-builtin-js
2
Add API & storage (for production)

For saving forms to the BizFirstAi backend and persisting drafts across sessions, add the API client and storage packages.

pnpm add @atlas-forms/api-client-js pnpm add @atlas-forms/storage-js pnpm add @atlas-forms/client-js
3
Register built-in controls

Call this once at your application entry point. It registers all 89+ built-in control types into the control registry singleton.

// main.tsx or App.tsx import { registerBuiltInControls } from '@atlas-forms/controls-builtin-js'; registerBuiltInControls();

Define your first form schema

A form schema is a JSON object. No code generation, no GUI required for basic forms — just declare what you need.

4
Create a form schema

Define controls, labels, validation rules, and default values. Every control has a unique id, a type from the 89+ available types, and optional validation.

// customer-onboarding.schema.ts import type { FormSchema } from '@atlas-forms/types-js'; export const customerOnboardingSchema: FormSchema = { version: "1.0.0", metadata: { name: "customer-onboarding", title: "Customer Onboarding", description: "New customer registration form" }, controls: [ { id: "first_name", type: "text", label: "First Name", required: true, order: 1, validation: { minLength: 2, maxLength: 50 } }, { id: "last_name", type: "text", label: "Last Name", required: true, order: 2 }, { id: "email", type: "email", label: "Email Address", required: true, order: 3, validation: { required: true } }, { id: "industry", type: "select", label: "Industry", order: 4, settings: { options: [ { value: "finance", label: "Financial Services" }, { value: "healthcare", label: "Healthcare" }, { value: "technology", label: "Technology" }, { value: "government", label: "Government" } ] } }, { id: "agree_terms", type: "checkbox", label: "I agree to the Terms of Service", required: true, order: 5, validation: { required: true } } ] };
5
Render the form

Wrap your component in FormStateProvider and pass the schema to FormRenderer. The provider initialises the FormEngine and Zustand state. FormRenderer handles the full submission lifecycle.

// OnboardingForm.tsx import { FormStateProvider } from '@atlas-forms/state-react'; import { FormRenderer } from '@atlas-forms/player-components-react'; import { customerOnboardingSchema } from './customer-onboarding.schema'; export function OnboardingForm() { const handleSubmit = async (values: Record<string, any>) => { console.log('Submitted:', values); // Call your API here }; return ( <FormStateProvider schema={customerOnboardingSchema} mode="edit"> <FormRenderer schema={customerOnboardingSchema} mode="edit" onSubmit={handleSubmit} submitLabel="Create Account" /> </FormStateProvider> ); }
The mode prop controls which controls are visible. Set mode="view" to show a read-only version of the same form — no code changes needed, just the prop.
6
Access form state with the hook

Use useAtlasForm() anywhere inside the FormStateProvider to read values, trigger validation, or reset the form.

import { useAtlasForm } from '@atlas-forms/state-react'; function SaveDraftButton() { const { values, isDirty, validate, reset } = useAtlasForm(); const handleSave = async () => { const result = await validate(); if (result.isValid) { // Save to storage console.log('Saving draft:', values); } }; return ( <button onClick={handleSave} disabled={!isDirty}> Save Draft </button> ); }

Add a custom validator

7
Register a custom validator

Register validators by name at startup. Reference the name in any control's schema. Works synchronously or asynchronously.

import { registerValidator } from '@atlas-forms/validation-js'; // Sync validator registerValidator('phone', (value) => { const valid = /^\+?1?\d{9,15}$/.test(String(value)); return valid ? { valid: true } : { valid: false, message: 'Enter a valid phone number' }; }); // Async validator (e.g. check email availability) registerValidator('emailAvailable', async (value) => { const res = await fetch(`/api/check-email?email=${value}`); const { available } = await res.json(); return available ? { valid: true } : { valid: false, message: 'This email is already registered' }; }); // Use in schema { id: "phone", type: "text", label: "Phone Number", validation: { customRule: "phone" } }
8
Register a custom control

Extend Atlas Forms with your own control types. Register them with the control registry and they appear in the palette and work in schemas exactly like built-in controls.

import { controlRegistry } from '@atlas-forms/control-registry-js'; import type { ControlPlugin } from '@atlas-forms/types-js'; import { PhoneInputControl } from './PhoneInputControl'; const phonePlugin: ControlPlugin = { type: 'phone-input', label: 'Phone Number', category: 'input', component: PhoneInputControl, defaultSettings: { countryCode: '+1', format: 'national' } }; controlRegistry.register(phonePlugin);
Custom controls appear immediately in Atlas Form Studio's drag-and-drop palette after registration. No rebuild required.

What to explore next

Multi-mode forms

Set modeVisibilitySettings on each control to show different fields in edit vs view vs admin mode. Build a single schema that serves all personas.

See example →

Stepper / multi-step forms

Use the stepper layout control to split a long form into labelled steps. Progress validation ensures a step is complete before advancing.

See stepper example →

AI form generation

Send a natural language description to the AI agent and receive a complete FormSchema JSON — full control types, validation rules, and layout configured automatically.

See AI generation →

Need help getting set up?

Ask in the Atlas Forms community or book a session with the BizFirstAi team.