Getting Started
Welcome! ð Usetheform is a lightweight, dependency-free React library for composing declarative forms and managing their state. It's simple to use, flexible, and powerful for handling nested fields, validation, and much more.
ðĨ Featuresâ
ðĶ Easy integration with libraries like React Select/Material UI and React Dropzone/Material UI Dropzone
â
Sync and Async validation
ð Schema support for Yup, Zod, Joi, Superstruct
ð§Ž Follows native HTML standards - see in action
ð§Đ Easy handling of arrays, objects, and nested structures - Nested collections, arrays, and objects made simple
ðĨ Tiny bundle size, zero dependencies â Check it on Bundlephobia
ð§ Motivationâ
Usetheform was created to provide a highly flexible, declarative way to handle forms in React with no dependencies. It supports:
ð§Đ Nested field structures: Build deeply structured forms with collections, arrays, and objects.
ð Synchronous & asynchronous validation: Validate inputs at every level â instantly or with async logic.
ð§ Custom input and reducer logic: Extend functionality using reducers and custom input components.
ð Schema-based validation: Integrate with Yup, Zod, Superstruct, or Joi for powerful schema validation.
ðŠķ Tiny footprint: Zero dependencies and optimized for performance.
If you find this library useful, please â the repo. It means a lot! ð
ð Installationâ
Install usetheform
using your preferred package manager:
- npm
- yarn
npm install usetheform --save
yarn add usetheform
⥠Quickstartâ
<Form onSubmit={state => alert(JSON.stringify(state))}> <Collection object name="user" as="div" className="mt-10 flex space-x-4"> <Input type="text" name="name" placeholder="Enter your name" /> <Input type="text" name="surname" placeholder="Enter your surname" /> </Collection> <Collection as="div" object name="nested" className="flex space-x-4 justify-between"> <Input type="text" name="name" placeholder="Enter nested name" /> <Input type="text" name="surname" placeholder="Enter nested surname" /> </Collection> <div className="mt-6 flex space-x-4"> <Input type="radio" name="gender" placeholder="M" value="M" /> <Input type="radio" name="gender" placeholder="F" value="F" /> <Input type="radio" name="gender" placeholder="Other" value="Other" /> </div> <Collection object name="options" as="div" className="flex space-x-4"> <Input type="checkbox" name="one" placeholder="Opt 1" checked /> <Input type="checkbox" name="second" placeholder="Opt 2" /> </Collection> <Collection as="div" array name="media" className="mt-6 flex justify-center space-x-4"> <Input type="file" /> <Input type="file" /> <Input type="file" /> </Collection> <div className="mt-6 flex justify-center space-x-4"> <Submit /> <Reset /> </div> </Form>
ð Recipesâ
ð First: create a form storeâ
interface FormState { counter: number; }
import { createFormStore } from 'usetheform';
import { FormState } from "./FormTypes";
const [formStore, useFormSelector] = createFormStore<FormState>({ counter: 0 });
export const awesomeFormStore = formStore;
export const useAwesomeFormSelector = useFormSelector;
ð Next: create your awesome Formâ
import { Form } from 'usetheform';
import { awesomeFormStore } from './awesomeFormStore';
import { FormState } from "./FormTypes";
export default function AwesomeForm() {
return (
<>
<Form<FormState> formStore={awesomeFormStore}>
<Input type="number" name="counter" value="0" placeholder="Counter" />
</Form>
<Counter />
</>
);
}
ð Finally: bind your components, and that's it!â
Use the useAwesomeFormSelector
hook anywhere, no providers needed. Select your state and the component will re-render on changes.
import { useAwesomeFormSelector } from './awesomeFormStore'
export const Counter = () => {
const [counter, setCounterValue] = useAwesomeFormSelector<"counter">((state) => state.counter);
return (
<div>
<span>{counter}</span>
<button type="button" onClick={() => setCounterValue((prev) => ++prev)}>
Increase Counter
</button>
<button type="button" onClick={() => setCounterValue((prev) => --prev)}>
Decrease Counter
</button>
<button type="button" onClick={() => setCounterValue(0)}>
Reset Counter
</button>
</div>
);
}
CodeSandbox Examplesâ
- Twitter 'What's Happening' Form Bar: Sandbox
- Shopping Cart: Sandbox
- Examples: Slider, Select, Collections etc..: Sandbox
- Various Implementations: Sandbox
- Wizard: Sandbox
- FormContext: Sandbox
- Material UI - React Select: Sandbox
- Validation using Yup, ZOD, JOI, Superstruct: Sandbox
- React Dropzone - Material UI Dropzone: Sandbox
Authorâ
Antonio Pangallo @antonio_pangall
â Stargazersâ
Contributingâ
ð First off, thanks for taking the time to contribute! ð
We would like to encourage everyone to help and support this library by contributing. See the CONTRIBUTING file.
Licenseâ
This software is free to use under the MIT license. See the LICENSE file for license text and copyright information.