From 6ca637601bc4d0410fafed94b820f927520df6b8 Mon Sep 17 00:00:00 2001 From: LeCarbonator <18158911+LeCarbonator@users.noreply.github.com> Date: Sat, 20 Dec 2025 17:34:23 +0100 Subject: [PATCH 1/3] docs: migrate installation to tabs --- docs/installation.md | 91 +++++++++++--------------------------------- docs/philosophy.md | 6 +-- 2 files changed, 25 insertions(+), 72 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index 14a917d7b..39457e3f6 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -5,82 +5,35 @@ title: Installation TanStack Form is compatible with various front-end frameworks, including React, Vue, and Solid. To use TanStack Form with your desired framework, install the corresponding adapter via your preferred package manager: -### React Example + -```bash -# npm -$ npm i @tanstack/react-form -# pnpm -$ pnpm add @tanstack/react-form -# bun -$ bun add @tanstack/react-form -# yarn -$ yarn add @tanstack/react-form -``` +react: @tanstack/react-form +vue: @tanstack/vue-form +angular: @tanstack/angular-form +solid: @tanstack/solid-form +lit: @tanstack/lit-form +svelte: @tanstack/svelte-form -### Vue Example +react: @tanstack/react-form-devtools # Optional: Form devtools +solid: @tanstack/solid-form-devtools # Optional: Form devtools -```bash -# npm -$ npm i @tanstack/vue-form -# pnpm -$ pnpm add @tanstack/vue-form -# bun -$ bun add @tanstack/vue-form -# yarn -$ yarn add @tanstack/vue-form -``` + -### Angular Example - -```bash -# npm -$ npm i @tanstack/angular-form -# pnpm -$ pnpm add @tanstack/angular-form -# bun -$ bun add @tanstack/angular-form -# yarn -$ yarn add @tanstack/angular-form -``` - -### Solid Example +> [!NOTE]- Polyfill requirements +> Depending on your environment, you might need to add polyfills. If you want to support older browsers, you need to transpile the library from `node_modules` yourself. -```bash -# npm -$ npm i @tanstack/solid-form -# pnpm -$ pnpm add @tanstack/solid-form -# bun -$ bun add @tanstack/solid-form -# yarn -$ yarn add @tanstack/solid-form -``` +## Meta-frameworks -### Lit Example +There are additional adapters for meta-frameworks such as: -```bash -# npm -$ npm i @tanstack/lit-form -# pnpm -$ pnpm add @tanstack/lit-form -# bun -$ bun add @tanstack/lit-form -# yarn -$ yarn add @tanstack/lit-form -``` +- TanStack Start +- Next.js +- Remix -### Svelte Example + -```bash -# npm -$ npm i @tanstack/svelte-form -# pnpm -$ pnpm add @tanstack/svelte-form -# bun -$ bun add @tanstack/svelte-form -# yarn -$ yarn add @tanstack/svelte-form -``` +react: @tanstack/react-form-start +react: @tanstack/react-form-nextjs +react: @tanstack/react-form-remix -> Depending on your environment, you might need to add polyfills. If you want to support older browsers, you need to transpile the library from `node_modules` yourself. + diff --git a/docs/philosophy.md b/docs/philosophy.md index 437118d46..9628ebbd0 100644 --- a/docs/philosophy.md +++ b/docs/philosophy.md @@ -45,13 +45,13 @@ When writing sufficiently correct TanStack Form code, you should not be able to Instead of: -```typescript +```ts useForm() ``` You should do: -```typescript +```ts interface Person { name: string age: number @@ -70,7 +70,7 @@ One of the main objectives of TanStack Form is that you should be wrapping it in To support this, we have a number of utilities that make it easier to build your own components and customized hooks: -```typescript +```ts // Exported from your own library with pre-bound components for your forms. export const { useAppForm, withForm } = createFormHook(/* options */) ``` From f7435a8d16da52af416ea6124e9f9fb18488521a Mon Sep 17 00:00:00 2001 From: LeCarbonator <18158911+LeCarbonator@users.noreply.github.com> Date: Tue, 13 Jan 2026 13:57:42 +0100 Subject: [PATCH 2/3] docs: update overview and installation --- docs/installation.md | 48 ++- docs/overview.md | 734 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 755 insertions(+), 27 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index 39457e3f6..cb45a3d48 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -3,9 +3,9 @@ id: installation title: Installation --- -TanStack Form is compatible with various front-end frameworks, including React, Vue, and Solid. To use TanStack Form with your desired framework, install the corresponding adapter via your preferred package manager: +TanStack Form is compatible with various front-end frameworks, including React, Vue, and Solid. Install the corresponding adapter for your framework using your preferred package manager: - + react: @tanstack/react-form vue: @tanstack/vue-form @@ -14,26 +14,54 @@ solid: @tanstack/solid-form lit: @tanstack/lit-form svelte: @tanstack/svelte-form -react: @tanstack/react-form-devtools # Optional: Form devtools -solid: @tanstack/solid-form-devtools # Optional: Form devtools - -> [!NOTE]- Polyfill requirements -> Depending on your environment, you might need to add polyfills. If you want to support older browsers, you need to transpile the library from `node_modules` yourself. + -## Meta-frameworks +# React -There are additional adapters for meta-frameworks such as: +# Meta-frameworks + +If you're using a meta-framework, TanStack Form provides additional adapters to streamline integration: - TanStack Start - Next.js - Remix - + + + react: @tanstack/react-form-start react: @tanstack/react-form-nextjs react: @tanstack/react-form-remix + + + +# React + +## Devtools + +Developer tools are available using [TanStack Devtools](https://tanstack.com/devtools/latest). Install the devtools adapter for your framework to debug forms and inspect their state. + +# Solid + +## Devtools + +Developer tools are available using [TanStack Devtools](https://tanstack.com/devtools/latest). Install the devtools adapter for your framework to debug forms and inspect their state. + + + + + +react: @tanstack/react-devtools +react: @tanstack/react-form-devtools +solid: @tanstack/solid-devtools +solid: @tanstack/solid-form-devtools + + + +> [!NOTE]- Polyfill requirements +> Depending on your environment, you might need to add polyfills. If you want to support older browsers, you need to transpile the library from `node_modules` yourself. diff --git a/docs/overview.md b/docs/overview.md index 22e42f1b6..4ea563e01 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -21,26 +21,24 @@ By providing a complete solution for these challenges, TanStack Form empowers de ## Enough talk, show me some code already! + + +# React + In the example below, you can see TanStack Form in action with the React framework adapter: [Open in CodeSandbox](https://codesandbox.io/s/github/tanstack/form/tree/main/examples/react/simple) -```tsx + + +```tsx title="App.tsx" import * as React from 'react' import { createRoot } from 'react-dom/client' +import { TanStackDevtools } from '@tanstack/react-devtools' +import { formDevtoolsPlugin } from '@tanstack/react-form-devtools' import { useForm } from '@tanstack/react-form' -import type { AnyFieldApi } from '@tanstack/react-form' -function FieldInfo({ field }: { field: AnyFieldApi }) { - return ( - <> - {field.state.meta.isTouched && !field.state.meta.isValid ? ( - {field.state.meta.errors.join(', ')} - ) : null} - {field.state.meta.isValidating ? 'Validating...' : null} - - ) -} +import { FieldInfo } from './FieldInfo.tsx' export default function App() { const form = useForm({ @@ -65,7 +63,7 @@ export default function App() { }} >
- {/* A type-safe field component */} + {/* A type-safe field component*/} [state.canSubmit, state.isSubmitting]} children={([canSubmit, isSubmitting]) => ( - + <> + +
+
+ + + + +
+ + + + `, +}) +export class AppComponent { + firstNameValidator: FieldValidateFn = ({ value }) => + !value + ? 'A first name is required' + : value.length < 3 + ? 'First name must be at least 3 characters' + : undefined + + firstNameAsyncValidator: FieldValidateAsyncFn = async ({ + value, + }) => { + await new Promise((resolve) => setTimeout(resolve, 1000)) + return value.includes('error') && 'No "error" allowed in first name' + } + + form = injectForm({ + defaultValues: { + firstName: '', + lastName: '', + }, + onSubmit({ value }) { + // Do something with form data + console.log(value) + }, + }) + + canSubmit = injectStore(this.form, (state) => state.canSubmit) + isSubmitting = injectStore(this.form, (state) => state.isSubmitting) + + handleSubmit(event: SubmitEvent) { + event.preventDefault() + event.stopPropagation() + this.form.handleSubmit() + } +} +``` + + + +# Solid + +In the example below, you can see TanStack Form in action with the Solid framework adapter: + +[Open in CodeSandbox](https://codesandbox.io/s/github/tanstack/form/tree/main/examples/solid/simple) + + + +```ts title="App.tsx" +/* @refresh reload */ +import { render } from 'solid-js/web' +import { createForm } from '@tanstack/solid-form' +import { FieldInfo } from './FieldInfo.tsx'; + +function App() { + const form = createForm(() => ({ + defaultValues: { + firstName: '', + lastName: '', + }, + onSubmit: async ({ value }) => { + // Do something with form data + console.log(value) + }, + })) + + return ( +
+

Simple Form Example

+
{ + e.preventDefault() + e.stopPropagation() + form.handleSubmit() + }} + > +
+ {/* A type-safe field component*/} + + !value + ? 'A first name is required' + : value.length < 3 + ? 'First name must be at least 3 characters' + : undefined, + onChangeAsyncDebounceMs: 500, + onChangeAsync: async ({ value }) => { + await new Promise((resolve) => setTimeout(resolve, 1000)) + return ( + value.includes('error') && 'No "error" allowed in first name' + ) + }, + }} + children={(field) => { + // Avoid hasty abstractions. Render props are great! + return ( + <> + + field().handleChange(e.target.value)} + /> + + + ) + }} + /> +
+
+ ( + <> + + field().handleChange(e.target.value)} + /> + + + )} + /> +
+ ({ + canSubmit: state.canSubmit, + isSubmitting: state.isSubmitting, + })} + children={(state) => { + return ( + + ) + }} + /> + +
+ ) +} + +const root = document.getElementById('root') + +render(() => , root!) +``` + +```ts title="FieldInfo.tsx" +import type { AnyFieldApi } from '@tanstack/solid-form' + +export interface FieldInfoProps { + field: AnyFieldApi +} + +export function FieldInfo(props: FieldInfoProps) { + return ( + <> + {props.field.state.meta.isTouched && !props.field.state.meta.isValid ? ( + {props.field.state.meta.errors.join(',')} + ) : null} + {props.field.state.meta.isValidating ? 'Validating...' : null} + + ) +} +``` + + + +# Svelte + +In the example below, you can see TanStack Form in action with the Svelte framework adapter: + +[Open in CodeSandbox](https://codesandbox.io/s/github/tanstack/form/tree/main/examples/svelte/simple) + + + +```svelte title="App.svelte" + + +
{ + e.preventDefault() + e.stopPropagation() + form.handleSubmit() + }} +> +

TanStack Form - Svelte Demo

+ + + value.length < 3 ? 'Not long enough' : undefined, + onChangeAsyncDebounceMs: 500, + onChangeAsync: async ({ value }) => { + await new Promise((resolve) => setTimeout(resolve, 1000)) + return value.includes('error') && 'No "error" allowed in first name' + }, + }} + > + {#snippet children(field)} +
+ + field.handleBlur()} + oninput={(e: Event) => { + const target = e.target as HTMLInputElement + field.handleChange(target.value) + }} + /> + +
+ {/snippet} +
+ + value.length < 3 ? 'Not long enough' : undefined, + }} + > + {#snippet children(field)} +
+ + field.handleBlur()} + oninput={(e: Event) => { + const target = e.target as HTMLInputElement + field.handleChange(target.value) + }} + /> + +
+ {/snippet} +
+ + {#snippet children(field)} +
+ + field.handleChange(!field.state.value)} + checked={field.state.value} + onblur={() => field.handleBlur()} + id={field.name} + type="checkbox" + /> +
+ {#if field.state.value} + + value.length === 0 ? 'If you have a job, you need a title' : null, + }} + > + {#snippet children(field)} +
+ + { + const target = e.target as HTMLInputElement + field.handleChange(target.value) + }} + /> + +
+ {/snippet} +
+ {/if} + {/snippet} +
+
+ ({ + canSubmit: state.canSubmit, + isSubmitting: state.isSubmitting, + })} + > + {#snippet children({ canSubmit, isSubmitting })} + + {/snippet} + + +
+
+``` + +```svelte title="FieldInfo.svelte" + + +{#if field.state.meta.isTouched} + {#each field.state.meta.errors as error} + {error} + {/each} + {field.state.meta.isValidating ? 'Validating...' : ''} +{/if} +``` + + + +# Lit + +In the example below, you can see TanStack Form in action with the Lit framework adapter: + +[Open in CodeSandbox](https://codesandbox.io/s/github/tanstack/form/tree/main/examples/lit/simple) + +```ts title="index.ts" +import { LitElement, html, nothing } from 'lit' +import { customElement } from 'lit/decorators.js' + +import { TanStackFormController } from '@tanstack/lit-form' +import { repeat } from 'lit/directives/repeat.js' + +@customElement('tanstack-form-demo') +export class TanStackFormDemo extends LitElement { + #form = new TanStackFormController(this, { + defaultValues: { + firstName: '', + lastName: '', + }, + onSubmit({ value }) { + // Do something with form data + console.log(value) + }, + }) + + render() { + return html` +
{ + e.preventDefault() + e.stopPropagation() + this.#form.api.handleSubmit() + }} + > + ${this.#form.field( + { + name: `firstName`, + validators: { + onChange: ({ value }) => + !value + ? 'A first name is required' + : value.length < 3 + ? 'First name must be at least 3 characters' + : undefined, + onChangeAsyncDebounceMs: 500, + onChangeAsync: async ({ value }) => { + await new Promise((resolve) => setTimeout(resolve, 1000)) + return ( + value.includes('error') && + 'No "error" allowed in first name' + ) + }, + }, + }, + (field) => { + return html`
+ + + ${field.state.meta.isTouched && !field.state.meta.isValid + ? html`${repeat( + field.state.meta.errors, + (__, idx) => idx, + (error) => { + return html`
${error}
` + }, + )}` + : nothing} + ${field.state.meta.isValidating + ? html`

Validating...

` + : nothing} +
` + }, + )} + +
+ ${this.#form.field( + { + name: `lastName`, + }, + (field) => { + return html`
+ + +
` + }, + )} +
+ + + +
+ ` + } +} ``` + + ## You talked me into it, so what now? - Learn TanStack Form at your own pace with our thorough [Walkthrough Guide](./installation) and [API Reference](./reference/classes/FormApi). From fef256fb33b91c0711d6ed555a5508664d7476c8 Mon Sep 17 00:00:00 2001 From: LeCarbonator <18158911+LeCarbonator@users.noreply.github.com> Date: Tue, 13 Jan 2026 14:05:56 +0100 Subject: [PATCH 3/3] docs: fix wrong heading --- docs/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installation.md b/docs/installation.md index cb45a3d48..c65bb92e2 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -20,7 +20,7 @@ svelte: @tanstack/svelte-form # React -# Meta-frameworks +## Meta-frameworks If you're using a meta-framework, TanStack Form provides additional adapters to streamline integration: