Type-safe, declarative and performant React form & validation library
A stable release has been reached. Further development of new features is currently not planned. Bug fixes will be provided if needed, feature requests wil still be considered.
- Fully type-safe API, purpose built to get the most out of Typescript type-inference
 - Declarative definition of form shape and validation rules
 - Runtime type-checking of form values against the schema
 - Convenient hooks & context based API allowing for isolated re-renders
 - Plain react-typescript, 0 dependencies
 - View layer agnostic - no components are provided, works with any 3rd-party components
 handleChangefunction for dealing with change events automatically- Advanced validation API which enables:
- specifying dependencies on other fields
 - specifying validation triggers for individual rules
 - selective validation of just the affected fields on value changes
 - separation of error messages from error codes (optional)
 - async validation rules with debounce option
 - easy mixing of built-in rules with custom functions
 - combining multiple validation rules into composite validators
 
 - Good scalability for very large and complex forms
 
npm install @virtuslab/formtsimport { FormSchemaBuilder, FormFields } from "@virtuslab/formts";
const Schema = new FormSchemaBuilder()
  .fields({ answer: FormFields.string() })
  .errors<string>()
  .build();import { FormValidatorBuilder } from "@virtuslab/formts";
const validator = new FormValidatorBuilder(Schema)
  .validate(
    Schema.answer,
    val => (val === "" ? "Required!" : null),
    val => (val !== "42" ? "Wrong answer!" : null)
  )
  .build();import { useFormController, FormProvider } from "@virtuslab/formts";
const MyForm: React.FC = () => {
  const controller = useFormController({ Schema, validator });
  return (
    <FormProvider controller={controller}>
      <AnswerField />
      <FormActions />
    </FormProvider>
  );
};import { useField } from "@virtuslab/formts";
const AnswerField: React.FC = () => {
  const field = useField(Schema.answer);
  return (
    <section>
      <label htmlFor={field.id}>
        What is the answer to the meaning of life, the universe, and everything?
      </label>
      <input
        id={field.id}
        value={field.value}
        onChange={field.handleChange}
        onBlur={field.handleBlur}
      />
      <div className="error">{field.error}</div>
    </section>
  );
};import { useFormHandle } from "@virtuslab/formts";
const FormActions: React.FC = () => {
  const form = useFormHandle(Schema);
  return (
    <section>
      <button
        type="submit"
        disabled={form.isValid === false}
        onClick={() => form.submit(console.log)}
      >
        Submit!
      </button>
      <button type="reset" onClick={form.reset}>
        Reset
      </button>
    </section>
  );
};Currently API documentation is available in form of:
- exhaustive JSDocs
 - TYPEDOC docs
 - CodeSandbox examples
 
Play around with the code on CodeSandbox to learn Formts API and features:
a) Step-by-step introduction:
- basic form (naive)
 - basic form + optimized re-renders
 - basic form + validation
 - basic form + Material-UI
 
b) HTML input bindings:
- radio group input
 - checkbox group input
 - select input
 - input array
 - mui multi-select input
 - mui date-picker input
 
c) Advanced examples:
- change password form
 - order pizza form
 - form with summary of validation errors
 - registration stepper form
 
Some of the reasons outlined below are no longer valid as react-hook-form has improved since this project started. It offers good type-safety and performance. If for some reason you are not happy with it however, this library offers different approach to many aspects of form management and a powerful validation API - so it may suit your needs better.
Most popular form libraries like Formik and react-hook-form are written in
Typescript but are not designed with type-safe API as a primary concern.
There is some evidence that this is important for some people:
- Reddit: Fully type-safe form libraries?
 - Formik issue: Strongly Typed Fields
 - react-hook-form extension: strictly-typed
 
There are some existing truly type-safe react form solutions, but each has a costly dependency associated with it:
- formstate --> 
MobX - Typescript.fun
--> 
fp-ts - ReForm --> 
ReasonML 
There are SOME form libraries with really good performance (react-hook-form). However combining convenient Context based hook API with React performance optimizations is still problematic. See https://react-hook-form.com/advanced-usage#FormProviderPerformance for example.
Usually form libs "outsource" advanced validation to schema-based libraries such
as Yup. This seems like a great idea but has some limitations:
yupand similar packages are not designed with type-safety in mind- Advanced optimizations (such as validating only the affected fields rather than the entire form) are not available.
 
- Form values type is limited by schema definition API and can't represent more advanced TS types
 - Adding 
requiredvalidator does not impact type of values. - number() fields are typed as 
number | "", this is because HTML number inputs work with""as empty value. - Definition of form shape and validation split into 2 separate steps
 - Binding to input components is more verbose than with other form libraries (this is intentional to keep API type-safe and view-layer agnostic)