AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
Kin Form: a fast, framework-agnostic form state library for TypeScript. Zero-dependency core, type-safe field paths, React and Lit bindings built in.
Developer toolsTypeScript · ShellGitHub @kintools-devOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Build your field components once. Reuse them everywhere. A framework-agnostic form state library for TypeScript.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Documentation ·
Get Started
Build your field components once. Reuse them everywhere.
A framework-agnostic form state library for TypeScript.
Forms read like composition, not wiring.
Each component receives a resolved FieldApi, not a path or form context.
Define the UI and behavior once, then mount it anywhere its value type fits. Kin
Form keeps that component independently subscribed, so a change only updates the
part of the form that depends on it. See
Form Composition for the
full pattern.Read the full README ↗Build your field components once. Reuse them everywhere.
A framework-agnostic form state library for TypeScript.
Forms read like composition, not wiring.
<form onSubmit={form.handleSubmit}>
<TextField api={form.field("email")} label="Email" />
<AddressField api={form.field("shipping")} />
<AddressField api={form.field("billing")} />
<ItemsField api={form.field("items")} />
<SubmitButton api={form}>Place order</SubmitButton>
</form>;
Each component receives a resolved FieldApi, not a path or form context.
Define the UI and behavior once, then mount it anywhere its value type fits. Kin
Form keeps that component independently subscribed, so a change only updates the
part of the form that depends on it. See
Form Composition for the
full pattern.
Reusable field components become awkward when a library treats the form as the only stateful object and fields as proxies into it. Nested objects, arrays, and shared validation then need their own special mechanisms.
Kin Form treats a form as a tree where every node (leaf, group, or the form
itself) is the same thing, with its own state, configuration, and subscribers.
That is why one component pattern works at every level. Dotted paths like
field("address.line1") type-check against that same tree, so a typo'd path is
a compile error, not a runtime surprise.
See kintools.dev/form for how the same value shape can be structured as different valid trees.
| Kin Form | React Hook Form | Formik | TanStack Form | |
|---|---|---|---|---|
| Zero dependencies | ✅ | ✅ | ❌ | ⚠️ |
| Framework-agnostic core | ✅ | ❌ | ❌ | ✅ |
| Type-safe nested field paths | ✅ | ⚠️ | ❌ | ✅ |
| Standard Schema support | ⚠️ | ⚠️ | ❌ | ✅ |
| Same primitive for field, group, array, and form | ✅ | ❌ | ❌ | ❌ |
| Localized subscription | ✅ | ❌ | ❌ | ❌ |
| Selective re-rendering | ✅ | ⚠️ | ⚠️ | ✅ |
| Built-in async-validation debounce | ✅ | ❌ | ❌ | ✅ |
| Declarative cross-field revalidation | ✅ | ⚠️ | ❌ | ✅ |
| Field state survives list virtualization | ✅ | ⚠️ | ✅ | ✅ |
✅ full support · ⚠️ partial or conditional · ❌ not supported
Each package's full public API, bundled and minified the same way (rolldown)
then gzipped. Reproduce with deno task --cwd scripts bundle-size. Not directly
comparable to Bundlephobia, which uses a different minifier (terser).
@kintools/form-core ██████░░░░░░░░░░░░░░░░░░ 4.5 KB
@kintools/form-react (bindings only) █░░░░░░░░░░░░░░░░░░░░░░░ 0.8 KB
@kintools/form-lit (bindings only) ██░░░░░░░░░░░░░░░░░░░░░░ 1.3 KB
@kintools/form-validators █░░░░░░░░░░░░░░░░░░░░░░░ 0.7 KB
Kin Form (core + react bindings) ███████░░░░░░░░░░░░░░░░░ 5.2 KB
Kin Form (core + lit bindings) ███████░░░░░░░░░░░░░░░░░ 5.5 KB
React Hook Form ██████████████████░░░░░░ 13.7 KB
Formik ██████████████████░░░░░░ 13.9 KB
TanStack Form ████████████████████████ 18.5 KB
Flat field update, 800x burst, wall-clock median in Happy DOM: 1.39 ms for
Kin Form vs 66.55 ms (React Hook Form), 3.30 ms (Formik), 564.24 ms (TanStack
Form). One scenario from a shared ~84-field benchmark form driven through the
same update plan against each library. Reproduce with
deno task --cwd scripts speed-bench.
See the full comparison for the complete scenario breakdown (nested/array updates, validation, mount cost), methodology notes, and code-by-code comparisons.
| Package | Description |
|---|---|
@kintools/form-core | FieldApi, FormApi — the framework-agnostic form engine |
@kintools/form-react | useForm, useWatch, useMultistep, Watch — React bindings |
@kintools/form-lit | watch, WatchController, MultistepController — Lit bindings |
@kintools/form-validators | required, minLength, maxLength, min, max, url, email, pattern, maxFileSize, password, toSchemaValidator() |
@kintools/form-devtools-react | DevtoolsProvider, useFormDevtools — inspector panel for a form's live tree state during development |
skills/kin-form teaches coding agents (Claude
Code, Cursor, Codex, ...) Kin Form's patterns and pitfalls. Install it with:
npx skills add kintools-dev/form
Or copy skills/kin-form/ into your project's .claude/skills/.
See CONTRIBUTING.md for project layout, running tests, and the PR process.