gform-react

gform-react

A lightweight, dependency-free TypeScript React form library built for performance, validation, and clean form logic.

gform-react is a lightweight React form library focused on three things: performance, validation, and clean form logic. It's dependency-free, fully typed, and tree-shakable - you import only what you use.

Why gform-react?

  • Minimal re-renders - only the fields that actually change re-render, not the whole form.
  • Native HTML constraint validation - required, min, max, pattern, minLength, maxLength, and more, with custom messages.
  • Custom & async validation - add any rule, including asynchronous server-side checks.
  • Works with Yup, Zod, and any validation library.
  • Deeply nested & dynamic forms - structure forms across components, add/remove fields at runtime without losing state.
  • Native <form> actions & Next.js Server Actions - no special adapters or client wiring.
  • Accessibility-friendly - auto-manages aria-required and aria-invalid.
  • Real file inputs - type="file" stores the actual File object, not C:\fakepath\….
  • React Native support - the same model on web and mobile via gform-react/native.

A 30-second taste

import { GForm, GInput, GValidator, type GValidators } from "gform-react";
 
interface SignInForm {
  username: string;
  password: string;
}
 
const validators: GValidators<SignInForm> = {
  "*": new GValidator().withRequiredMessage("This field is required"),
};
 
export default function App() {
  return (
    <GForm<SignInForm>
      validators={validators}
      onSubmit={(state, e) => {
        e.preventDefault();
        console.log(state.toRawData());
      }}
    >
      {(state) => (
        <>
          <GInput
            formKey="username"
            required
            element={(input, props) => (
              <label>
                <input {...props} placeholder="username" />
                {input.error && <small>{input.errorText}</small>}
              </label>
            )}
          />
          <button disabled={state.isInvalid}>Sign in</button>
        </>
      )}
    </GForm>
  );
}
New here?

Head to Getting Started to install the package, then read Core Concepts to understand GForm, GInput, and form state.

Where to go next