TypeScript-first React forms

Elegant React forms,
with or without the boilerplate.

Generate a complete, validated form from a schema with AutoForm — or take full control with the useForm hook. Bring Zod, Yup, Valibot, a custom validator, or none.

$npm install el-form-react
React 16.8+Zero dependencies on a validatorMIT licensed
ContactForm.tsxAutoForm
import { AutoForm } from "el-form-react-components";
import "el-form-react-components/styles.css";
import { z } from "zod";

const contactSchema = z.object({
  name: z.string().min(1, "Name is required"),
  email: z.string().email("Invalid email"),
  message: z.string().min(10, "Message too short"),
});

function ContactForm() {
  return <AutoForm schema={contactSchema} onSubmit={handle} />;
}
Two APIs, one library

Start from a schema. Drop down to the hook when you need the wheel.

One line gets you a complete form. When a flow demands bespoke logic, the same library hands you full programmatic control — no migration, no rewrite.

The fast path
AutoForm

Pass a schema; get a complete, validated, styled form. Fields, errors, and submit wiring are generated for you.

Use whenyou want a correct form now and the schema is the source of truth.
import { AutoForm } from "el-form-react-components";
import "el-form-react-components/styles.css";
import { z } from "zod";

const contactSchema = z.object({
  name: z.string().min(1, "Name is required"),
  email: z.string().email("Invalid email"),
  message: z.string().min(10, "Message too short"),
});

function ContactForm() {
  return (
    <AutoForm schema={contactSchema} onSubmit={(data) => console.log(data)} />
  );
}
The control path
useForm

A React Hook Form-compatible hook. Register fields, own your markup, and handle submission exactly how you like.

Use whenthe layout is custom, the logic is bespoke, or you're migrating from RHF.
import { useForm } from "el-form-react-hooks";

function CustomForm() {
  const { register, handleSubmit, formState } = useForm({
    defaultValues: { email: "", message: "" },
  });

  return (
    <form onSubmit={handleSubmit((data) => console.log(data))}>
      <input {...register("email")} placeholder="Email" />
      <textarea {...register("message")} placeholder="Message" />
      <button type="submit">Submit</button>
    </form>
  );
}
Validation-agnostic

Bring your own validation.

Swap validators without rewriting the form. The schema is an input, not a lock-in — start with Zod today, move to Valibot tomorrow, drop validation entirely for a prototype.

Zod v3 / v4YupValibotCustom functionNone

One form component. schema in, validated data out — whatever the source.

Why El Form

Built for developers who want control and convenience.

01

Type-safe inference

Field names, values, and errors are inferred from your schema. The compiler catches typos before your users do.

02

Minimal re-renders

State is isolated per field, so typing in one input doesn't re-render the whole form. Fast by default, even at scale.

03

Styled out of the box

AutoForm ships clean, accessible defaults you can theme — or override entirely. Beautiful before you touch the CSS.

04

RHF-compatible API

useForm mirrors React Hook Form's surface — register, handleSubmit, formState. Migrate with muscle memory intact.

05

Modular packages

Install only the layer you need — hooks, components, or both. No mandatory UI bundle riding along for the trip.

06

Framework-friendly

Works with Next.js, Vite, Remix, and CRA. React 16.8 and up — wherever your app already lives, El Form fits.

Ship the form, not the boilerplate

From schema to form in one line.

Install the package, point AutoForm at a schema, and you have a validated form. Reach for the hook the moment you need the wheel.

$npm install el-form-react