Introduction
@saastro/forms is a dynamic form system for React applications. It combines the power of React Hook Form, Zod validation, and dependency injection to create type-safe, configurable forms with 30+ field types.
Why @saastro/forms?
Build complex forms with minimal code, maximum type safety, and full UI flexibility.
Traditional form libraries make you choose: either you get type safety and write a lot of boilerplate, or you get convenience and lose type safety. @saastro/forms gives you both:
- Zero-config mode — Auto-discover shadcn components, no Provider needed
- Type-safe configuration — Full TypeScript support with autocomplete
- JSON-serializable — Store form configs in databases, send over APIs
- Declarative validation — Zod schemas or simple rules objects
- UI agnostic — Bring your own components via dependency injection
- 30+ field types — Text, select, slider, date, checkbox groups, and more
- Multi-step forms — Built-in wizard support with progress indicators
- Conditional logic — Show/hide/disable fields based on values
Key Features
1. Zero-Config Mode (Recommended)
The simplest way to get started — just pass your components:
import { Form, FormBuilder } from '@saastro/forms';
// Auto-discover all shadcn components with Vite's glob
const uiComponents = import.meta.glob('@/components/ui/*.tsx', { eager: true });
const config = FormBuilder.create('contact')
.addField('name', (f) => f.type('text').label('Name').required())
.addField('email', (f) => f.type('email').label('Email').required().email())
.addStep('main', ['name', 'email'])
.build();
function ContactForm() {
return (
<Form config={config} components={uiComponents} onSubmit={(values) => console.log(values)} />
);
}
2. FormBuilder API
Fluent, chainable API for building forms:
const config = FormBuilder.create('contact')
.layout('manual') // Fixed 12-column grid
.columns(12)
.addField(
'name',
(f) =>
f.type('text').label('Name').required('Name is required').columns({ default: 12, md: 6 }), // Full width mobile, half on md+
)
.addField('email', (f) =>
f
.type('email')
.label('Email')
.required()
.email('Please enter a valid email')
.columns({ default: 12, md: 6 }),
)
.addStep('main', ['name', 'email'])
.build();
3. JSON Configuration
Same forms, defined as JSON (perfect for CMSes and visual builders):
{
"id": "contact",
"columns": 12,
"fields": {
"name": {
"type": "text",
"label": "Name",
"schema": { "required": true, "requiredMessage": "Name is required" },
"columns": { "default": 12, "md": 6 }
},
"email": {
"type": "email",
"label": "Email",
"schema": { "required": true, "format": "email" },
"columns": { "default": 12, "md": 6 }
}
},
"steps": [{ "name": "main", "fields": ["name", "email"] }]
}
4. Dependency Injection
Use any UI library. Pass components directly or use a Provider:
// Zero-config (recommended)
<Form config={config} components={uiComponents} />
// Or explicit components
<Form
config={config}
components={{
Input: MyCustomInput,
Button: MyCustomButton,
}}
/>
// Or legacy Provider pattern
<ComponentProvider components={registry}>
<Form config={config} />
</ComponentProvider>
Field Types
@saastro/forms includes 30+ field types out of the box:
| Category | Fields |
|---|---|
| Text | text, email, tel, textarea, input-group |
| Selection | select, native-select, combobox, command, radio, button-radio |
| Toggle | checkbox, switch, checkbox-group, switch-group, button-checkbox |
| Special | slider, date, daterange, otp, button-card, html |
When to Use @saastro/forms
Perfect for:
- Dynamic forms that change based on configuration
- Visual form builders and CMSes
- Multi-step wizards and onboarding flows
- Applications that need consistent form UX
- Teams that want type-safe form development
Consider alternatives if:
- You need a single, static form (just use React Hook Form directly)
- You’re not using React
- You need server-side form handling (consider Remix forms)
Architecture
@saastro/forms
├── FormBuilder # Fluent API for building configs
├── Form # Main render component (zero-config ready)
├── ComponentProvider # DI container for UI components (optional)
├── PluginManager # Extensibility (analytics, autosave, etc.)
├── Validation # Zod schema compiler from JSON rules
└── Renderers # Field type implementations
Ready to Start?
Head to the Installation guide to set up @saastro/forms in your project.
Or browse the Field Types to see all available fields with interactive examples.