Introduction

Formisch is a schema-based, headless form library for Preact. It manages form state and validation. It is type-safe, fast by default and its bundle size is small due to its modular design. Try it out in our playground!

Highlights

  • Small bundle size starting at 2.5 kB
  • Schema-based validation with Valibot
  • Type safety with autocompletion in editor
  • It's fast – DOM updates are fine-grained
  • Minimal, readable and well thought out API
  • Supports all native HTML form fields

Example

Every form starts with the useForm hook. It initializes your form's store based on the provided Valibot schema and infers its types. Next, wrap your form in the <Form /> component. It's a thin layer around the native <form /> element that handles form validation and submission. Then, you can access the state of a field with the useField hook or the <Field /> component to connect your inputs.

import { Field, Form, useForm } from '@formisch/preact';
import * as v from 'valibot';

const LoginSchema = v.object({
  email: v.pipe(v.string(), v.email()),
  password: v.pipe(v.string(), v.minLength(8)),
});

export default function LoginPage() {
  const loginForm = useForm({
    schema: LoginSchema,
  });

  return (
    <Form of={loginForm} onSubmit={(output, event) => console.log(output)}>
      <Field of={loginForm} path={['email']}>
        {(field) => (
          <div>
            <input {...field.props} value={field.input} type="email" />
            {field.errors.value && <div>{field.errors.value[0]}</div>}
          </div>
        )}
      </Field>
      <Field of={loginForm} path={['password']}>
        {(field) => (
          <div>
            <input {...field.props} value={field.input} type="password" />
            {field.errors.value && <div>{field.errors.value[0]}</div>}
          </div>
        )}
      </Field>
      <button type="submit">Login