Installation
Learn how to install and configure @saastro/forms in your React project.
Prerequisites
Before you begin, make sure you have:
- React 18 or later
- TypeScript 5.0 or later (recommended)
- A UI component library (we recommend shadcn/ui)
Quick Start
1. Install the package
npm install @saastro/forms
# or
pnpm add @saastro/forms
# or
bun add @saastro/forms
2. Install peer dependencies
@saastro/forms requires React Hook Form, Zod, and date-fns:
npm install react-hook-form zod date-fns react-day-picker
3. Install shadcn/ui components
Install only the components you need. For a basic text form:
npx shadcn@latest add input button label field form
For all available field types:
npx shadcn@latest add input button label textarea select checkbox radio-group popover calendar tooltip slider switch separator dialog command input-otp field form
4. Create your first form (Zero-Config)
The simplest way to use @saastro/forms — auto-discover all your shadcn components with Vite’s glob:
import { Form, FormBuilder } from '@saastro/forms';
// Auto-discover all shadcn components at build time
const uiComponents = import.meta.glob('@/components/ui/*.tsx', { eager: true });
const config = FormBuilder.create('contact')
.addField('name', (f) => f.type('text').label('Name').required().minLength(2))
.addField('email', (f) => f.type('email').label('Email').required().email())
.addStep('main', ['name', 'email'])
.buttons({ submit: { type: 'submit', label: 'Send' } })
.build();
export function ContactForm() {
return (
<Form
config={config}
components={uiComponents}
onSubmit={(values) => console.log('Submitted:', values)}
/>
);
}
That’s it! No FormProvider, no barrel file, no manual component registration. The Form auto-discovers components by parsing the glob result.
Alternative: Explicit Components
If you prefer explicit imports or need to override specific components:
import { Form, FormBuilder } from '@saastro/forms';
import { Input, Button, Label } from '@/components/ui';
import { Field, FieldLabel, FieldDescription, FieldError } from '@/components/ui/field';
import { FormField, FormControl } from '@/components/ui/form';
<Form
config={config}
components={{
Input,
Button,
Label,
Field,
FieldLabel,
FieldDescription,
FieldError,
FormField,
FormControl,
}}
/>;
Provider Mode (Legacy)
For apps with many forms sharing the same components, you can use the provider pattern:
import { Form, FormBuilder, ComponentProvider, createComponentRegistry } from '@saastro/forms';
import * as shadcn from '@/lib/form-components'; // Your barrel file
const registry = createComponentRegistry(shadcn);
export function App() {
return (
<ComponentProvider components={registry}>
<ContactForm />
<SignupForm />
<CheckoutForm />
</ComponentProvider>
);
}
function ContactForm() {
const config = FormBuilder.create('contact')
.addField('name', (f) => f.type('text').label('Name').required())
.addStep('main', ['name'])
.build();
return <Form config={config} />;
}
Benefits of Zero-Config
- One line of setup — just
import.meta.globand you’re done - Auto-discovers components — no manual registration needed
- Missing component fallback — shows helpful warnings with install commands
- No Provider boilerplate — just render
<Form /> - Override per-form — mix glob with explicit overrides
Required Components by Field Type
When a component is missing, you’ll see a helpful warning with install instructions.
| Field Type | Required Components |
|---|---|
text, email, tel | Input, Label, Field, FieldLabel, FieldError, FormField, FormControl |
textarea | Textarea, Label, Field, FieldLabel, FieldError, FormField, FormControl |
select | Select, SelectTrigger, SelectContent, SelectItem, SelectValue, Field, … |
checkbox, switch | Checkbox/Switch, Label, Field, … |
date | Calendar, Popover, PopoverTrigger, PopoverContent, Button, Field, … |
combobox | Command, CommandInput, CommandList, Popover, Button, Field, … |
Check Required Components Programmatically
import { getRequiredComponents, getInstallCommand } from '@saastro/forms';
const required = getRequiredComponents(config);
// ['Input', 'Button', 'Label', 'Field', ...]
const installCmd = getInstallCommand(required);
// 'npx shadcn@latest add input button label field form'
Tailwind CSS 4
If you’re using Tailwind CSS 4, add the following @source directive to your main CSS file so Tailwind can detect the classes used by this package:
@source "node_modules/@saastro/forms/dist/**/*.js";
TypeScript Configuration
For the best experience, ensure your tsconfig.json includes:
{
"compilerOptions": {
"strict": true,
"moduleResolution": "bundler",
"paths": {
"@/*": ["./src/*"]
}
}
}
Next Steps
- Learn the FormBuilder API — the recommended way to build forms
- Set up Validation — Zod schemas or declarative rules
- Build Multi-Step Forms — wizards with conditional routing
- Browse the Field Types to see all available fields