npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-informed

v1.9.2

Published

Form library providing an easy way to create forms with react

Downloads

82

Readme

Informed is a set of components to reduce the work needed to create forms with react.

There are already many different form solution in the react ecosystem. Informed tries to be different by minimizing boilerplate. Informed does not require decorated input elements, either. Typescript definitions are provided for easier form refactoring.

Click here to view a demo.

<Form value={form}
      preventAction={true}
      onChange={(form) => this.setState({form})}>

    <div>
        <label htmlFor={form.firstName.name}>First Name</label>
        <Field value={form.firstName} 
               debounce={50}>
            <input type="text"
                   placeholder="First Name"
                   disabled={form.isSubmitted}
            />
        </Field>
    </div>

    <div>
        <label htmlFor={form.lastName.name}>Last Name</label>
        <Field value={form.lastName}
               debounce="onBlur">
            <input type="text"
                   placeholder="Last Name"
                   disabled={form.isSubmitted}
            />
        </Field>
    </div>

    <div>
        <button disabled={!form.isValid || form.isSubmitted}
                className="btn btn-primary"
                type="submit">
            submit
        </button>
    </div>
</Form>

Run examples

See the docs/examples/ directory for examples on how to use this library. To run the examples locally:

npm install
npm start 

and open your browser to http://localhost:8000/ (if it doesn't open automatically)

Goals

  • Input elements should not be passed as props or wrapped in odd ways.
    • There should be full control over look and feel using standard HTML props
  • Un-opinionated about how form state is stored
    • set the form based on props like with a redux-store sol'n
    • or make use of a containing component's state
  • Easily integrates custom components (just implement the value/onChange interface)
  • Typescript integration
  • limit the amount of unnecessary boilerplate needed for controlled elements by automatically adding the needed value/onChange props

Form State Object

Every Form state object implements the BaseForm interface. There are several fields that provide summary info about the form (is<*>).

export interface BaseForm {
    /** true if the form was submitted. */
    isSubmitted?: boolean;
    /** true if any of the form fields have errors. If a field can only have an error if it is dirty.  */
    isError?: boolean;
    /** true if there are no errors on any fields. Unlike isError, this checks fields regardless of their dirty flag. */
    isValid?: boolean;
    /** true if the form values are different from their original values */
    isChanged?: boolean;

    [k: string]: any;
}

Finally, each Field is stored as a property where the name of the Field is set to an InputState object.

InputState

Each InputState object has several properties that get updated automatically allowing to easily update the UI in response to events like form errors.

There may be some confusion about the difference between error and honestError. For example, a that is required but initialized with an empty value will immediately have an error. But we wouldn't really indicate an error unless the user had attempted to modify the input and then left its value blank. To avoid having to perform tests against the dirty property, the error property is provided.

export interface InputState<T> {
    /** property name of Field */
    name: string;
    /** Non-zero when the Field has an error (always 0 when dirty === false) */
    error: number;
    /** Non-zero when the Field has an error. Even when dirty === false) */
    honestError: number;
    /** value of Field*/
    value: T;
    /** True if the user has changed the form. Initial value is false */
    dirty: boolean;
    /** true if the current value is different (shallow comparison) from the original */
    changed: boolean;
}

Field Usage

should be a direct wrapper around the input element or custom component you want to use. If you need to use a or similar to control positioning this should be placed around instead.

If you look at the inspected html you can see that does not create a wrapper

Save Form State

The element is configured like a regular controlled component. Implement the 'value' and 'onChange' props and the rest of the form takes care of itself

    <Form value={form}
          onChange={(form) => this.setState({form})}>
          ...
    </Form>

Future Goals and TODOs

  • Field does not update when props of a Field is changed manually
  • 'validate' prop interface should accept a Promise for async validation

Examples

  • classic POST form