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

@ez-kit/form-react

v0.2.0

Published

Framework-agnostic React adapter for @ez-kit/form — DI field layer with zero visual styling.

Readme

@ez-kit/form-react

The React adapter for @ez-kit/form-*: a dependency-injection layer over TanStack Form that turns a UI kit's primitives into flat, fully-wired field components hanging off the form instance.

This package contains zero visual styling. It renders only the primitives a kit injects, plus data-* attributes for that kit's CSS to target. Install a kit package (@ez-kit/form-shadcn, @ez-kit/form-heroui) unless you are building your own.

The idea

createForm({ components }) returns a useForm that is a superset of TanStack Form's:

const form = useForm({
	defaultValues: { email: '', age: 0, role: 'user', agree: false },
	validators: { onChange: zodSchema }, // native standard-schema, no custom resolver
	onSubmit: ({ value }) => save(value),
})

<form.Form>
	<form.TextField name='email' label='Email' placeholder='[email protected]' />
	<form.NumberField name='age' label='Age' />
	<form.SelectField name='role' label='Role' options={[{ label: 'User', value: 'user' }]} />
	<form.CheckboxField name='agree' label='I agree' />
	<form.SubmitButton>Save</form.SubmitButton>

	{/* the native TanStack API is untouched on the same instance */}
	<form.Field name='email'>{(field) => <input value={field.state.value} />}</form.Field>
	<form.Subscribe selector={(s) => s.errors}>{(errors) => <pre>{errors.length}</pre>}</form.Subscribe>
</form.Form>

Each *Field renders label + input + description + error text itself. name is narrowed to the paths in your form data whose value type fits the field, so <form.NumberField name='email' /> is a compile error.

Building a kit

Implement FormComponents and hand it to createForm:

import { createForm } from '@ez-kit/form-react'
import type { FormComponents } from '@ez-kit/form-react'

const components = {
	TextField,
	NumberField,
	TextareaField,
	SelectField,
	CheckboxField,
	Button,
	Form,
} satisfies FormComponents

export const { useForm } = createForm({ components })

satisfies FormComponents turns a forgotten field into a compile error rather than a runtime crash. Components are bound by closure at createForm time — no runtime provider is involved.

This package renders no elements at all — not even a field wrapper. It hands each kit one flat props object per field (identity, label, description, errors, invalid, value/onChange, onBlur) and the kit builds the entire tree. That is what lets a React-Aria kit nest its Label / Description / FieldError inside the field root, where the library's own id and validation wiring lives, while a plain-DOM kit keeps them as siblings.

Styling hooks

Two attributes travel with every field for the kit to spread onto its root, plus one on the form:

| Attribute | Where | Value | | ----------------- | -------------- | ------------------------------------------------------ | | data-field | the kit's root | the field's name | | data-field-type | the kit's root | text / number / textarea / select / checkbox | | data-form | the <form> | always present |

Accessibility is the kit's to wire, because only the kit knows its markup. The shared layer supplies the raw material: a stable id, the label and description nodes, and the normalised errors.

License

MIT