S

Installation

How to install and configure @saastro/forms in your React project.

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

  1. One line of setup — just import.meta.glob and you’re done
  2. Auto-discovers components — no manual registration needed
  3. Missing component fallback — shows helpful warnings with install commands
  4. No Provider boilerplate — just render <Form />
  5. 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 TypeRequired Components
text, email, telInput, Label, Field, FieldLabel, FieldError, FormField, FormControl
textareaTextarea, Label, Field, FieldLabel, FieldError, FormField, FormControl
selectSelect, SelectTrigger, SelectContent, SelectItem, SelectValue, Field, …
checkbox, switchCheckbox/Switch, Label, Field, …
dateCalendar, Popover, PopoverTrigger, PopoverContent, Button, Field, …
comboboxCommand, 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