# Installation

URL: https://docs.forms.saastro.io/docs/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 (Recommended)

`@saastro/forms` ships with a CLI that scaffolds example forms and installs
everything they need — shadcn components and peer dependencies. The fastest
path is three commands:

```bash
# 1. Install the package
npm install @saastro/forms

# 2. Generate two example forms (zero-config) in src/components/
npx @saastro/forms init

# 3. Install any missing shadcn components AND peer dependencies
npx @saastro/forms install-deps
```

That's it. Open `src/components/ExampleForm.tsx` to see a `FormBuilder` example,
or `src/components/ExampleFormJson.tsx` for the equivalent JSON-config form.

> **Vite only:** the scaffolded examples auto-discover components with
> `import.meta.glob`, which is a Vite feature — it does not exist in Next.js,
> webpack, or other bundlers. On non-Vite setups, pass components explicitly
> via the `components` prop instead (see
> [Explicit Components](#alternative-explicit-components) below and the
> [Recipes](/docs/recipes) for framework-specific examples).

See the [CLI reference](/docs/installation/cli) for every flag and option.

### How `init` and `install-deps` work

- **`init`** creates two example files in `src/components/`:
  - `ExampleForm.tsx` — programmatic form with `FormBuilder`
  - `ExampleFormJson.tsx` — JSON-config form with auto-discovered components
- **`install-deps`**:
  1. Reads your project's `components.json` (shadcn config) and runs
     `shadcn@latest add ...` for any required components that are missing.
  2. Detects your package manager from the lockfile and installs any missing
     peer dependencies (`zod`, `react-hook-form`, `react-day-picker`,
     `date-fns`).

Both commands need a `components.json` (shadcn config) in your project root and
exit if it's missing — if you don't have one yet, run `npx shadcn@latest init`
first.

### Use the form in your page

```tsx

  return <ExampleForm />;
}
```

The form auto-discovers shadcn components via Vite's `import.meta.glob`. No
`FormProvider` and no barrel file required.

---

## Manual Setup

If you prefer to wire things up by hand, follow these four steps instead of
running the CLI.

### 1. Install the package

```bash
npm install @saastro/forms
# or
pnpm add @saastro/forms
# or
bun add @saastro/forms
```

### 2. Import the stylesheet

Add this once to your app entry point (e.g. `main.tsx`, `layout.tsx`, or `globals.css`):

```ts
```

This provides the selected-state styles for button groups (`button-radio`, `button-checkbox`, `button-card`). It uses CSS custom properties from your design system — no Tailwind compilation needed.

> **Server Components / SSR:** `@saastro/forms` is a client-side library (hooks, state, events) but is safe to import on the server — all `window`/`document` access is guarded. In React Server Components setups (Next.js App Router), render `<Form>` inside a `'use client'` boundary.

### 3. Install peer dependencies

`@saastro/forms` requires React Hook Form, Zod, date-fns, and react-day-picker:

```bash
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:

```bash
npx shadcn@latest add input button label field form
```

For all available field types:

```bash
npx shadcn@latest add input button label textarea select checkbox radio-group popover calendar tooltip slider switch separator dialog command input-otp native-select field form
```

### 4. Create your first form (Zero-Config)

If your project uses Vite, auto-discover all your shadcn components with
`import.meta.glob`:

```tsx

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();

  return (
    <Form
      config={config}
      components={uiComponents}
      onSubmit={(values) => console.log('Submitted:', values)}
    />
  );
}
```

No `FormProvider`, no barrel file, no manual component registration. The Form
auto-discovers components by parsing the glob result.

> **Not using Vite?** `import.meta.glob` is Vite-specific. On Next.js, webpack,
> or any other bundler, skip this step and pass the components explicitly — the
> next section shows how, and it works everywhere.

---

## Alternative: Explicit Components

If you're not using Vite, prefer explicit imports, or need to override specific
components, pass them directly to the `components` prop. This works with every
bundler:

```tsx

<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:

```tsx

const registry = createComponentRegistry(shadcn);

  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

Zero-config mode requires Vite, but when available it's the least amount of code:

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 the install command
4. **No Provider boilerplate** — just render `<Form />`
5. **Override per-form** — to replace a discovered component, convert the glob
   with `parseGlobModules` (exported from `@saastro/forms`) and spread your
   override over the result: `components={{ ...parseGlobModules(modules), Input: MyInput }}`

---

## Required Components by Field Type

When a component is missing, you'll see a helpful warning with the recommended
fix: `npx @saastro/forms install-deps`.

| Field Type             | Required Components                                                       |
| ---------------------- | ------------------------------------------------------------------------- |
| `text`, `email`, `tel` | Input, Label, Field, FieldLabel, FieldDescription, FieldError, FormField, FormControl |
| `textarea`             | Textarea, Label, Field, FieldLabel, FieldDescription, 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

```tsx

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:

```css
@source "node_modules/@saastro/forms/dist/**/*.js";
```

---

## TypeScript Configuration

`@saastro/forms` itself has no special TypeScript requirements. The settings
below are what the examples in these docs (and the CLI-generated files) assume:

```json
{
  "compilerOptions": {
    "strict": true,
    "moduleResolution": "bundler",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}
```

The `@/*` paths alias is the standard shadcn/ui convention — it's where the
examples import UI components from (`@/components/ui/...`). Adjust it to match
your project layout if yours differs.

---

## Next Steps

- Read the [CLI reference](/docs/installation/cli) for every CLI command and flag
- Learn the [FormBuilder API](/docs/formbuilder) — the recommended way to build forms
- Set up [Validation](/docs/validation) — Zod schemas or declarative rules
- Build [Multi-Step Forms](/docs/multi-step) — wizards with conditional routing
- Browse the [Field Types](/fields) to see all available fields
- Check the [Recipes](/docs/recipes) for framework-specific setups (Next.js and other non-Vite bundlers)
