gform-react
A lightweight, dependency-free TypeScript React form library built for performance, validation, and clean form logic.
Why gform-react?
The whole point of gform-react is that it should feel closer to writing native forms than to configuring a library.
- Tiny & no dependencies - ~4.8 KB gzipped, tree‑shakable
- Minimal re-renders - updates only the fields that actually change
- Native HTML constraint validation - full support for
min,max,pattern,minLength,maxLength,required, and more - Schema validation via Standard Schema v1 - any library implementing the spec works out of the box (Zod, Valibot, ArkType, Yup, …); drive the whole form from one schema via
GValidator.withSchema/withSchemaAsync, including object-level cross-field rules with zero runtime dependencies - Custom & async validation - add any rule via
withCustomValidation, including asynchronous server-side checks withwithCustomValidationAsync - Cross-field validation - re-validate a field when another changes (e.g. confirm-password) via
validatorDeps - Deeply Nested Forms - structure forms however you like, structure forms however you like, split a big form into focused and reusable components
- Dynamic fields - add or remove fields at runtime without losing state
- Native
<form>actions - fully supports browser‑level form submission, including action, method, and HTTP navigation, with no JavaScript required - Next.js Server Actions support - works seamlessly with Server Actions through standard
<form>submissions, with no special adapters or client‑side wiring - Custom data on any input - attach arbitrary data to a field via
dispatchChanges(option lists, loading flags, fetched metadata); it's kept in form state for your UI, separate from the submitted value - Accessibility‑friendly - automatically manages
aria-requiredandaria-invalid - File inputs -
type="file"stores the realFileobject (orFile[]withmultiple), not theC:\fakepath\...string - React Native support - the same API on web and mobile (via
gform-react/native); no adapters, no separate mental model
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
placeholder="username"
element={(input, props) => (
<label>
<input {...props} />
{input.error && <small>{input.errorText}</small>}
</label>
)}
/>
<button disabled={state.isInvalid}>Sign in</button>
</>
)}
</GForm>
);
}New here?
Head to Installation to install the package, read
Core Concepts to understand GForm, GInput, and form state,
then build Your First Form.
Where to go next
- Installation - install the package and wire up peer dependencies.
- Core Concepts - the typed interface, the
validatorsobject, and theGFormcomponent. - Your First Form - build and run a small validated form in a few lines.
- Validation - native constraints, custom messages, async, Yup/Zod.
- API Reference - every export and the shared state types, with links to each guide.
- Examples & Playground - live, editable forms you can run in the browser.