diff --git a/.changeset/config.json b/.changeset/config.json
index 67493148e..0c2ce612d 100644
--- a/.changeset/config.json
+++ b/.changeset/config.json
@@ -8,7 +8,13 @@
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
- "fixed": [],
+ "fixed": [
+ [
+ "@tanstack/form-devtools",
+ "@tanstack/react-form-devtools",
+ "@tanstack/solid-form-devtools"
+ ]
+ ],
"linked": [],
"ignore": []
}
diff --git a/docs/framework/solid/guides/devtools.md b/docs/framework/solid/guides/devtools.md
new file mode 100644
index 000000000..d832c9e34
--- /dev/null
+++ b/docs/framework/solid/guides/devtools.md
@@ -0,0 +1,60 @@
+---
+id: devtools
+title: Devtools
+---
+
+TanStack Form comes with a ready to go suit of devtools.
+
+## Setup
+
+Install the [TanStack Devtools](https://tanstack.com/devtools/latest/docs/quick-start) library and the [TanStack Form plugin](http://npmjs.com/package/@tanstack/solid-form-devtools), from the framework adapter that your working in (in this case `@tanstack/solid-devtools`, and `@tanstack/solid-form-devtools`).
+
+```bash
+npm i @tanstack/solid-devtools
+npm i @tanstack/solid-form-devtools
+```
+
+Next in the root of your application import the `TanStackDevtools`.
+
+```tsx
+import { TanStackDevtools } from '@tanstack/solid-devtools'
+
+import App from './App'
+
+render(
+ () => (
+ <>
+
+
+
+ >
+ ),
+ root!,
+)
+```
+
+Import the `FormDevtoolsPlugin` from **TanStack Form** and provide it to the `TanStackDevtools` component.
+
+```tsx
+import { TanStackDevtools } from '@tanstack/solid-devtools'
+import { formDevtoolsPlugin } from '@tanstack/solid-form-devtools'
+
+import App from './app'
+
+const root = document.getElementById('root')
+
+render(
+ () => (
+ <>
+
+
+
+ >
+ ),
+ root!,
+)
+```
+
+Finally add any additional configuration you desire to the `TanStackDevtools` component, more information can be found under the [TanStack Devtools Configuration](https://tanstack.com/devtools/) section.
+
+A complete working example can be found in our [examples section](https://tanstack.com/form/latest/docs/framework/solid/examples/devtools).
diff --git a/examples/react/devtools/src/index.tsx b/examples/react/devtools/src/index.tsx
index 535dfda34..feae77cd8 100644
--- a/examples/react/devtools/src/index.tsx
+++ b/examples/react/devtools/src/index.tsx
@@ -2,7 +2,7 @@ import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { TanStackDevtools } from '@tanstack/react-devtools'
-import { FormDevtoolsPlugin } from '@tanstack/react-form-devtools'
+import { formDevtoolsPlugin } from '@tanstack/react-form-devtools'
import App from './App'
@@ -10,6 +10,6 @@ createRoot(document.getElementById('root')!).render(
-
+
,
)
diff --git a/examples/solid/devtools/.gitignore b/examples/solid/devtools/.gitignore
new file mode 100644
index 000000000..a547bf36d
--- /dev/null
+++ b/examples/solid/devtools/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/examples/solid/devtools/README.md b/examples/solid/devtools/README.md
new file mode 100644
index 000000000..99613fc0a
--- /dev/null
+++ b/examples/solid/devtools/README.md
@@ -0,0 +1,28 @@
+## Usage
+
+```bash
+$ npm install # or pnpm install or yarn install
+```
+
+### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs)
+
+## Available Scripts
+
+In the project directory, you can run:
+
+### `npm run dev`
+
+Runs the app in the development mode.
+Open [http://localhost:5173](http://localhost:5173) to view it in the browser.
+
+### `npm run build`
+
+Builds the app for production to the `dist` folder.
+It correctly bundles Solid in production mode and optimizes the build for the best performance.
+
+The build is minified and the filenames include the hashes.
+Your app is ready to be deployed!
+
+## Deployment
+
+Learn more about deploying your application with the [documentations](https://vitejs.dev/guide/static-deploy.html)
diff --git a/examples/solid/devtools/index.html b/examples/solid/devtools/index.html
new file mode 100644
index 000000000..3cff6100b
--- /dev/null
+++ b/examples/solid/devtools/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ TanStack Form Solid Devtools Example App
+
+
+
+
+
+
diff --git a/examples/solid/devtools/package.json b/examples/solid/devtools/package.json
new file mode 100644
index 000000000..343f11fe4
--- /dev/null
+++ b/examples/solid/devtools/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "@tanstack/form-example-solid-devtools",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc && vite build",
+ "test:types": "tsc",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@tanstack/solid-devtools": "^0.7.0",
+ "@tanstack/solid-form": "^1.23.5",
+ "@tanstack/solid-form-devtools": "workspace:*",
+ "solid-js": "^1.9.9"
+ },
+ "devDependencies": {
+ "typescript": "5.8.2",
+ "vite": "^7.1.6",
+ "vite-plugin-solid": "^2.11.8"
+ }
+}
diff --git a/examples/solid/devtools/src/app.tsx b/examples/solid/devtools/src/app.tsx
new file mode 100644
index 000000000..dc95e078c
--- /dev/null
+++ b/examples/solid/devtools/src/app.tsx
@@ -0,0 +1,112 @@
+import { createForm } from '@tanstack/solid-form'
+import type { AnyFieldApi } from '@tanstack/solid-form'
+
+interface FieldInfoProps {
+ field: AnyFieldApi
+}
+
+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}
+ >
+ )
+}
+
+export default function App() {
+ const form = createForm(() => ({
+ defaultValues: {
+ firstName: '',
+ lastName: '',
+ },
+ onSubmit: async ({ value }) => {
+ // Do something with form data
+ console.log(value)
+ },
+ }))
+
+ return (
+
+
Simple Form Example
+
({
+ canSubmit: state.canSubmit,
+ isSubmitting: state.isSubmitting,
+ })}
+ children={(state) => {
+ return (
+
+ {state().isSubmitting ? '...' : 'Submit'}
+
+ )
+ }}
+ />
+
+
+ )
+}
diff --git a/examples/solid/devtools/src/index.tsx b/examples/solid/devtools/src/index.tsx
new file mode 100644
index 000000000..2752cfb20
--- /dev/null
+++ b/examples/solid/devtools/src/index.tsx
@@ -0,0 +1,21 @@
+// lib
+import { render } from 'solid-js/web'
+
+import { TanStackDevtools } from '@tanstack/solid-devtools'
+import { formDevtoolsPlugin } from '@tanstack/solid-form-devtools'
+
+// components
+import App from './app'
+
+const root = document.getElementById('root')
+
+render(
+ () => (
+ <>
+
+
+
+ >
+ ),
+ root!,
+)
diff --git a/examples/solid/devtools/tsconfig.json b/examples/solid/devtools/tsconfig.json
new file mode 100644
index 000000000..576a7f010
--- /dev/null
+++ b/examples/solid/devtools/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "module": "ESNext",
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "Bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "preserve",
+ "jsxImportSource": "solid-js",
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["src", "vite.config.ts"]
+}
diff --git a/examples/solid/devtools/vite.config.ts b/examples/solid/devtools/vite.config.ts
new file mode 100644
index 000000000..4095d9be5
--- /dev/null
+++ b/examples/solid/devtools/vite.config.ts
@@ -0,0 +1,6 @@
+import { defineConfig } from 'vite'
+import solid from 'vite-plugin-solid'
+
+export default defineConfig({
+ plugins: [solid()],
+})
diff --git a/packages/form-devtools/package.json b/packages/form-devtools/package.json
index bad47c168..b811d75c0 100644
--- a/packages/form-devtools/package.json
+++ b/packages/form-devtools/package.json
@@ -52,7 +52,8 @@
"src"
],
"dependencies": {
- "@tanstack/devtools-ui": "^0.3.5",
+ "@tanstack/devtools-ui": "^0.4.0",
+ "@tanstack/devtools-utils": "^0.0.4",
"@tanstack/form-core": "workspace:*",
"clsx": "^2.1.1",
"dayjs": "^1.11.18",
diff --git a/packages/form-devtools/src/components/DetailsPanel.tsx b/packages/form-devtools/src/components/DetailsPanel.tsx
index b7cef5dae..607937306 100644
--- a/packages/form-devtools/src/components/DetailsPanel.tsx
+++ b/packages/form-devtools/src/components/DetailsPanel.tsx
@@ -116,7 +116,7 @@ export function DetailsPanel({ selectedKey }: DetailsPanelProps) {
>
{fieldName}
-
+
)}
@@ -128,7 +128,7 @@ export function DetailsPanel({ selectedKey }: DetailsPanelProps) {
)}
diff --git a/packages/form-devtools/src/components/index.tsx b/packages/form-devtools/src/components/index.tsx
index ce268441f..09297be60 100644
--- a/packages/form-devtools/src/components/index.tsx
+++ b/packages/form-devtools/src/components/index.tsx
@@ -1,8 +1,7 @@
import { FormEventClientProvider } from '../contexts/eventClientContext'
-
import { Shell } from './Shell'
-export function Devtools() {
+export default function Devtools() {
return (
diff --git a/packages/form-devtools/src/core.tsx b/packages/form-devtools/src/core.tsx
index ab2af1dc2..e94637630 100644
--- a/packages/form-devtools/src/core.tsx
+++ b/packages/form-devtools/src/core.tsx
@@ -1,47 +1,10 @@
import { lazy } from 'solid-js'
-import { render } from 'solid-js/web'
-import { Devtools } from './components'
+import { constructCoreClass } from '@tanstack/devtools-utils/solid'
-export interface FormDevtoolsInit {}
-
-class FormDevtoolsCore {
- #isMounted = false
- #dispose?: () => void
- #ThemeProvider: any
-
- constructor(_init?: FormDevtoolsInit | undefined) {}
-
- mount(el: T, theme: 'light' | 'dark') {
- if (this.#isMounted) {
- throw new Error('Devtools is already mounted')
- }
+const Component = lazy(() => import('./components'))
- this.#ThemeProvider = lazy(() =>
- import('@tanstack/devtools-ui').then((mod) => ({
- default: mod.ThemeContextProvider,
- })),
- )
- const ThemeProvider = this.#ThemeProvider
-
- const dispose = render(() => {
- return (
-
-
-
- )
- }, el)
-
- this.#isMounted = true
- this.#dispose = dispose
- }
+export interface FormDevtoolsInit {}
- unmount() {
- if (!this.#isMounted) {
- throw new Error('Devtools is not mounted')
- }
- this.#dispose?.()
- this.#isMounted = false
- }
-}
+const [FormDevtoolsCore, FormDevtoolsCoreNoOp] = constructCoreClass(Component)
-export { FormDevtoolsCore }
+export { FormDevtoolsCore, FormDevtoolsCoreNoOp }
diff --git a/packages/form-devtools/src/index.ts b/packages/form-devtools/src/index.ts
index 57de6e589..2875778dc 100644
--- a/packages/form-devtools/src/index.ts
+++ b/packages/form-devtools/src/index.ts
@@ -2,16 +2,9 @@
import * as Devtools from './core'
-// Create a dummy class for production that does nothing
-class DummyFormDevtoolsCore {
- constructor() {}
- mount() {}
- unmount() {}
-}
-
-export const FormDevtoolsCore: (typeof Devtools)['FormDevtoolsCore'] =
+export const FormDevtoolsCore =
process.env.NODE_ENV !== 'development'
- ? (DummyFormDevtoolsCore as any)
+ ? Devtools.FormDevtoolsCoreNoOp
: Devtools.FormDevtoolsCore
export type { FormDevtoolsInit } from './core'
diff --git a/packages/form-devtools/src/production.ts b/packages/form-devtools/src/production.ts
index 94fcf423c..0607f56eb 100644
--- a/packages/form-devtools/src/production.ts
+++ b/packages/form-devtools/src/production.ts
@@ -1,7 +1,5 @@
'use client'
-import * as Devtools from './core'
-
-export const FormDevtoolsCore = Devtools.FormDevtoolsCore
+export { FormDevtoolsCore } from './core'
export type { FormDevtoolsInit } from './core'
diff --git a/packages/react-form-devtools/package.json b/packages/react-form-devtools/package.json
index e7b239349..c354d4aa8 100644
--- a/packages/react-form-devtools/package.json
+++ b/packages/react-form-devtools/package.json
@@ -52,6 +52,7 @@
"src"
],
"dependencies": {
+ "@tanstack/devtools-utils": "^0.0.3",
"@tanstack/form-devtools": "workspace:*"
},
"devDependencies": {
diff --git a/packages/react-form-devtools/src/FormDevtools.tsx b/packages/react-form-devtools/src/FormDevtools.tsx
index 5293d786b..a0b005bb7 100644
--- a/packages/react-form-devtools/src/FormDevtools.tsx
+++ b/packages/react-form-devtools/src/FormDevtools.tsx
@@ -1,30 +1,12 @@
-import { useEffect, useRef } from 'react'
+import { createReactPanel } from '@tanstack/devtools-utils/react'
+import { FormDevtoolsCore } from '@tanstack/form-devtools'
-import type { FormDevtoolsCore } from '@tanstack/form-devtools'
+// type
+import type { DevtoolsPanelProps } from '@tanstack/devtools-utils/react'
-export interface FormDevtoolsReactInit {
- theme?: 'light' | 'dark'
-}
+export interface FormDevtoolsReactInit extends DevtoolsPanelProps {}
-export const FormDevtools = (props?: FormDevtoolsReactInit) => {
- const devToolRef = useRef(null)
- const devtools = useRef | null>(null)
+const [FormDevtoolsPanel, FormDevtoolsPanelNoOp] =
+ createReactPanel(FormDevtoolsCore)
- useEffect(() => {
- if (devtools.current) return
-
- import('@tanstack/form-devtools').then(({ FormDevtoolsCore }) => {
- devtools.current = new FormDevtoolsCore()
-
- if (devToolRef.current) {
- devtools.current.mount(devToolRef.current, props?.theme ?? 'dark')
- }
- })
-
- return () => {
- devtools.current?.unmount()
- }
- }, [props?.theme])
-
- return
-}
+export { FormDevtoolsPanel, FormDevtoolsPanelNoOp }
diff --git a/packages/react-form-devtools/src/devtools-production.tsx b/packages/react-form-devtools/src/devtools-production.tsx
deleted file mode 100644
index edc85245e..000000000
--- a/packages/react-form-devtools/src/devtools-production.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-'use client'
-
-import * as Devtools from './FormDevtools'
-
-export const FormDevtoolsPanel = Devtools.FormDevtools
-
-export type { FormDevtoolsReactInit } from './FormDevtools'
-
-export function formDevtoolsPlugin() {
- return {
- name: 'TanStack Form',
- render: (_el: HTMLElement, theme: 'light' | 'dark') => {
- return
- },
- }
-}
diff --git a/packages/react-form-devtools/src/devtools.tsx b/packages/react-form-devtools/src/devtools.tsx
deleted file mode 100644
index 259b76831..000000000
--- a/packages/react-form-devtools/src/devtools.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-'use client'
-import React from 'react'
-import * as Devtools from './FormDevtools'
-
-export const FormDevtools: (typeof Devtools)['FormDevtools'] =
- process.env.NODE_ENV !== 'development'
- ? function () {
- return React.createElement('div')
- }
- : Devtools.FormDevtools
-
-export function FormDevtoolsPlugin() {
- return {
- name: 'TanStack Form',
- render: (_el: HTMLElement, theme: 'light' | 'dark') => {
- return
- },
- }
-}
diff --git a/packages/react-form-devtools/src/index.ts b/packages/react-form-devtools/src/index.ts
index 39356ff2a..729970b78 100644
--- a/packages/react-form-devtools/src/index.ts
+++ b/packages/react-form-devtools/src/index.ts
@@ -1 +1,16 @@
-export * from './devtools'
+'use client'
+
+import * as Devtools from './FormDevtools'
+import * as plugin from './plugin'
+
+export const FormDevtoolsPanel =
+ process.env.NODE_ENV !== 'development'
+ ? Devtools.FormDevtoolsPanelNoOp
+ : Devtools.FormDevtoolsPanel
+
+export const formDevtoolsPlugin =
+ process.env.NODE_ENV !== 'development'
+ ? plugin.formDevtoolsNoOpPlugin
+ : plugin.formDevtoolsPlugin
+
+export type { FormDevtoolsReactInit } from './FormDevtools'
diff --git a/packages/react-form-devtools/src/plugin.tsx b/packages/react-form-devtools/src/plugin.tsx
new file mode 100644
index 000000000..2455b55b6
--- /dev/null
+++ b/packages/react-form-devtools/src/plugin.tsx
@@ -0,0 +1,9 @@
+import { createReactPlugin } from '@tanstack/devtools-utils/react'
+import { FormDevtoolsPanel } from './FormDevtools'
+
+const [formDevtoolsPlugin, formDevtoolsNoOpPlugin] = createReactPlugin(
+ 'TanStack Form',
+ FormDevtoolsPanel,
+)
+
+export { formDevtoolsPlugin, formDevtoolsNoOpPlugin }
diff --git a/packages/react-form-devtools/src/production.ts b/packages/react-form-devtools/src/production.ts
index 4dac26de7..98685231c 100644
--- a/packages/react-form-devtools/src/production.ts
+++ b/packages/react-form-devtools/src/production.ts
@@ -1 +1,7 @@
-export * from './devtools-production'
+'use client'
+
+export { FormDevtoolsPanel } from './FormDevtools'
+
+export type { FormDevtoolsReactInit } from './FormDevtools'
+
+export { formDevtoolsPlugin } from './plugin'
diff --git a/packages/solid-form-devtools/CHANGELOG.md b/packages/solid-form-devtools/CHANGELOG.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/packages/solid-form-devtools/eslint.config.js b/packages/solid-form-devtools/eslint.config.js
new file mode 100644
index 000000000..e472c69e7
--- /dev/null
+++ b/packages/solid-form-devtools/eslint.config.js
@@ -0,0 +1,10 @@
+// @ts-check
+
+import rootConfig from '../../eslint.config.js'
+
+export default [
+ ...rootConfig,
+ {
+ rules: {},
+ },
+]
diff --git a/packages/solid-form-devtools/package.json b/packages/solid-form-devtools/package.json
new file mode 100644
index 000000000..3a273bfda
--- /dev/null
+++ b/packages/solid-form-devtools/package.json
@@ -0,0 +1,63 @@
+{
+ "name": "@tanstack/solid-form-devtools",
+ "version": "0.3.1",
+ "description": "Solid adapter for devtools for Form.",
+ "author": "Tanner Linsley",
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/TanStack/form.git",
+ "directory": "packages/form"
+ },
+ "homepage": "https://tanstack.com/form",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "type": "module",
+ "types": "dist/esm/index.d.ts",
+ "module": "dist/esm/index.js",
+ "exports": {
+ ".": {
+ "import": {
+ "types": "./dist/esm/index.d.ts",
+ "default": "./dist/esm/index.js"
+ }
+ },
+ "./production": {
+ "import": {
+ "types": "./dist/esm/production.d.ts",
+ "default": "./dist/esm/production.js"
+ }
+ },
+ "./package.json": "./package.json"
+ },
+ "sideEffects": false,
+ "engines": {
+ "node": ">=18"
+ },
+ "files": [
+ "dist/",
+ "src"
+ ],
+ "scripts": {
+ "clean": "premove ./build ./dist",
+ "lint:fix": "eslint ./src --fix",
+ "test:eslint": "eslint ./src",
+ "test:lib": "vitest",
+ "test:lib:dev": "pnpm test:lib --watch",
+ "test:types": "tsc",
+ "test:build": "publint --strict",
+ "build": "vite build"
+ },
+ "peerDependencies": {
+ "solid-js": ">=1.9.7"
+ },
+ "dependencies": {
+ "@tanstack/devtools-utils": "^0.0.3",
+ "@tanstack/form-devtools": "workspace:*"
+ },
+ "devDependencies": {
+ "vite-plugin-solid": "^2.11.8"
+ }
+}
diff --git a/packages/solid-form-devtools/src/FormDevtools.tsx b/packages/solid-form-devtools/src/FormDevtools.tsx
new file mode 100644
index 000000000..38fe3dee1
--- /dev/null
+++ b/packages/solid-form-devtools/src/FormDevtools.tsx
@@ -0,0 +1,10 @@
+import { createSolidPanel } from '@tanstack/devtools-utils/solid'
+import { FormDevtoolsCore } from '@tanstack/form-devtools'
+import type { DevtoolsPanelProps } from '@tanstack/devtools-utils/solid'
+
+const [FormDevtoolsPanel, FormDevtoolsPanelNoOp] =
+ createSolidPanel(FormDevtoolsCore)
+
+export interface FormDevtoolsSolidInit extends DevtoolsPanelProps {}
+
+export { FormDevtoolsPanel, FormDevtoolsPanelNoOp }
diff --git a/packages/solid-form-devtools/src/index.ts b/packages/solid-form-devtools/src/index.ts
new file mode 100644
index 000000000..47b057337
--- /dev/null
+++ b/packages/solid-form-devtools/src/index.ts
@@ -0,0 +1,14 @@
+import * as Devtools from './FormDevtools'
+import * as plugin from './plugin'
+
+export const FormDevtools =
+ process.env.NODE_ENV !== 'development'
+ ? Devtools.FormDevtoolsPanelNoOp
+ : Devtools.FormDevtoolsPanel
+
+export const formDevtoolsPlugin =
+ process.env.NODE_ENV !== 'development'
+ ? plugin.formDevtoolsNoOpPlugin
+ : plugin.formDevtoolsPlugin
+
+export type { FormDevtoolsSolidInit } from './FormDevtools'
diff --git a/packages/solid-form-devtools/src/plugin.tsx b/packages/solid-form-devtools/src/plugin.tsx
new file mode 100644
index 000000000..323b72be1
--- /dev/null
+++ b/packages/solid-form-devtools/src/plugin.tsx
@@ -0,0 +1,9 @@
+import { createSolidPlugin } from '@tanstack/devtools-utils/solid'
+import { FormDevtoolsPanel } from './FormDevtools'
+
+const [formDevtoolsPlugin, formDevtoolsNoOpPlugin] = createSolidPlugin(
+ 'TanStack Form',
+ FormDevtoolsPanel,
+)
+
+export { formDevtoolsPlugin, formDevtoolsNoOpPlugin }
diff --git a/packages/solid-form-devtools/src/production.ts b/packages/solid-form-devtools/src/production.ts
new file mode 100644
index 000000000..cc8f6131d
--- /dev/null
+++ b/packages/solid-form-devtools/src/production.ts
@@ -0,0 +1,5 @@
+export { FormDevtoolsPanel } from './FormDevtools'
+
+export type { FormDevtoolsSolidInit } from './FormDevtools'
+
+export { formDevtoolsPlugin } from './plugin'
diff --git a/packages/solid-form-devtools/tests/index.test.ts b/packages/solid-form-devtools/tests/index.test.ts
new file mode 100644
index 000000000..350ef3ade
--- /dev/null
+++ b/packages/solid-form-devtools/tests/index.test.ts
@@ -0,0 +1,7 @@
+import { describe, expect, it } from 'vitest'
+
+describe('test suite', () => {
+ it('should work', () => {
+ expect(true).toBe(true)
+ })
+})
diff --git a/packages/solid-form-devtools/tests/test-setup.ts b/packages/solid-form-devtools/tests/test-setup.ts
new file mode 100644
index 000000000..a9d0dd31a
--- /dev/null
+++ b/packages/solid-form-devtools/tests/test-setup.ts
@@ -0,0 +1 @@
+import '@testing-library/jest-dom/vitest'
diff --git a/packages/solid-form-devtools/tsconfig.docs.json b/packages/solid-form-devtools/tsconfig.docs.json
new file mode 100644
index 000000000..2880b4dfa
--- /dev/null
+++ b/packages/solid-form-devtools/tsconfig.docs.json
@@ -0,0 +1,4 @@
+{
+ "extends": "./tsconfig.json",
+ "include": ["tests", "src"]
+}
diff --git a/packages/solid-form-devtools/tsconfig.json b/packages/solid-form-devtools/tsconfig.json
new file mode 100644
index 000000000..3ee4c951e
--- /dev/null
+++ b/packages/solid-form-devtools/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": "../../tsconfig.json",
+ "include": ["src", "eslint.config.js", "vite.config.ts", "tests"],
+ "compilerOptions": {
+ "jsx": "preserve",
+ "jsxImportSource": "solid-js"
+ }
+}
diff --git a/packages/solid-form-devtools/vite.config.ts b/packages/solid-form-devtools/vite.config.ts
new file mode 100644
index 000000000..7473089b2
--- /dev/null
+++ b/packages/solid-form-devtools/vite.config.ts
@@ -0,0 +1,25 @@
+import { defineConfig, mergeConfig } from 'vitest/config'
+import { tanstackViteConfig } from '@tanstack/config/vite'
+import solid from 'vite-plugin-solid'
+import packageJson from './package.json'
+
+const config = defineConfig({
+ plugins: [solid()],
+ test: {
+ name: packageJson.name,
+ dir: './',
+ watch: false,
+ environment: 'jsdom',
+ setupFiles: ['./tests/test-setup.ts'],
+ globals: true,
+ },
+})
+
+export default mergeConfig(
+ config,
+ tanstackViteConfig({
+ entry: ['./src/index.ts', './src/production.ts'],
+ srcDir: './src',
+ cjs: false,
+ }),
+)
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b5dd27fb5..81d38112e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -886,6 +886,31 @@ importers:
specifier: ^2.11.8
version: 2.11.8(@testing-library/jest-dom@6.8.0)(solid-js@1.9.9)(vite@7.1.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(sass@1.90.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.43.1)(tsx@4.19.4)(yaml@2.8.0))
+ examples/solid/devtools:
+ dependencies:
+ '@tanstack/solid-devtools':
+ specifier: ^0.7.0
+ version: 0.7.2(csstype@3.1.3)(solid-js@1.9.9)
+ '@tanstack/solid-form':
+ specifier: ^1.23.5
+ version: link:../../../packages/solid-form
+ '@tanstack/solid-form-devtools':
+ specifier: workspace:*
+ version: link:../../../packages/solid-form-devtools
+ solid-js:
+ specifier: ^1.9.9
+ version: 1.9.9
+ devDependencies:
+ typescript:
+ specifier: 5.8.2
+ version: 5.8.2
+ vite:
+ specifier: ^7.1.6
+ version: 7.1.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(sass@1.90.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.43.1)(tsx@4.19.4)(yaml@2.8.0)
+ vite-plugin-solid:
+ specifier: ^2.11.8
+ version: 2.11.8(@testing-library/jest-dom@6.8.0)(solid-js@1.9.9)(vite@7.1.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(sass@1.90.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.43.1)(tsx@4.19.4)(yaml@2.8.0))
+
examples/solid/large-form:
dependencies:
'@tanstack/solid-form':
@@ -1197,8 +1222,11 @@ importers:
packages/form-devtools:
dependencies:
'@tanstack/devtools-ui':
- specifier: ^0.3.5
- version: 0.3.5(csstype@3.1.3)(solid-js@1.9.9)
+ specifier: ^0.4.0
+ version: 0.4.0(csstype@3.1.3)(solid-js@1.9.9)
+ '@tanstack/devtools-utils':
+ specifier: ^0.0.4
+ version: 0.0.4(@types/react@19.1.6)(csstype@3.1.3)(react@19.1.0)(solid-js@1.9.9)
'@tanstack/form-core':
specifier: workspace:*
version: link:../form-core
@@ -1274,6 +1302,9 @@ importers:
packages/react-form-devtools:
dependencies:
+ '@tanstack/devtools-utils':
+ specifier: ^0.0.3
+ version: 0.0.3(@types/react@19.1.6)(csstype@3.1.3)(react@19.1.0)(solid-js@1.9.9)
'@tanstack/form-devtools':
specifier: workspace:*
version: link:../form-devtools
@@ -1313,6 +1344,22 @@ importers:
specifier: ^2.11.8
version: 2.11.8(@testing-library/jest-dom@6.8.0)(solid-js@1.9.9)(vite@7.1.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(sass@1.90.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.43.1)(tsx@4.19.4)(yaml@2.8.0))
+ packages/solid-form-devtools:
+ dependencies:
+ '@tanstack/devtools-utils':
+ specifier: ^0.0.3
+ version: 0.0.3(@types/react@19.1.6)(csstype@3.1.3)(react@19.1.0)(solid-js@1.9.9)
+ '@tanstack/form-devtools':
+ specifier: workspace:*
+ version: link:../form-devtools
+ solid-js:
+ specifier: '>=1.9.7'
+ version: 1.9.9
+ devDependencies:
+ vite-plugin-solid:
+ specifier: ^2.11.8
+ version: 2.11.8(@testing-library/jest-dom@6.8.0)(solid-js@1.9.9)(vite@7.1.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(sass@1.90.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.43.1)(tsx@4.19.4)(yaml@2.8.0))
+
packages/svelte-form:
dependencies:
'@tanstack/form-core':
@@ -4782,12 +4829,54 @@ packages:
peerDependencies:
solid-js: '>=1.9.7'
+ '@tanstack/devtools-ui@0.4.0':
+ resolution: {integrity: sha512-kiCfKnfuPWz1VWOKIr3kkWXMMvwu6GOR/SSu2AjTOu/CxkDSl57DVvOHJDNE6PDd5gN7JPn/46R9Rg8jcrR6nA==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ solid-js: '>=1.9.7'
+
+ '@tanstack/devtools-utils@0.0.3':
+ resolution: {integrity: sha512-7FIIOIuMPQZ42FpXureF4vdMbjyTLCfVIEhSDInjDjSOtoEbkIUtw+HK25GyldOG2uLs1iYNij+Ln675KT0iBw==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/react': '>=19.0.0'
+ react: '>=19.0.0'
+ solid-js: '>=1.9.7'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ react:
+ optional: true
+ solid-js:
+ optional: true
+
+ '@tanstack/devtools-utils@0.0.4':
+ resolution: {integrity: sha512-oEZzBQqX6V9oTmDAj6W45iGDRbCO3B/UMTqwktTaagCPDUDRTDFBVUcdYs+QXVNaE6JQ/jDHmIHig/5bG4ot5g==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@types/react': '>=19.0.0'
+ react: '>=19.0.0'
+ solid-js: '>=1.9.7'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ react:
+ optional: true
+ solid-js:
+ optional: true
+
'@tanstack/devtools@0.6.14':
resolution: {integrity: sha512-dOtHoeLjjcHeNscu+ZEf89EFboQsy0ggb6pf8Sha59qBUeQbjUsaAvwP8Ogwg89oJxFQbTP7DKYNBNw5CxlNEA==}
engines: {node: '>=18'}
peerDependencies:
solid-js: '>=1.9.7'
+ '@tanstack/devtools@0.6.16':
+ resolution: {integrity: sha512-KUP4RAiikKMoL+M3ltIrN4p0trAI4tbYHsLh7BHS2iCb79jGP2vWqKjpT1NazaRakF2sMoEloXePKjSNwYcbVQ==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ solid-js: '>=1.9.7'
+
'@tanstack/directive-functions-plugin@1.131.2':
resolution: {integrity: sha512-5Pz6aVPS0BW+0bLvMzWsoajfjI6ZeWqkbVBaQfIbSTm4DOBO05JuQ/pb7W7m3GbCb5TK1a/SKDhuTX6Ag5I7UQ==}
engines: {node: '>=12'}
@@ -4903,6 +4992,12 @@ packages:
resolution: {integrity: sha512-hWsaSgEZAVyzHg8+IcJWCEtfI9ZSlNELErfLiGHG9XCHEXMegFWsrESsKHlASzJqef9RsuOLDl+1IMPIskwdDw==}
engines: {node: '>=12'}
+ '@tanstack/solid-devtools@0.7.2':
+ resolution: {integrity: sha512-ad2S/oSwZeU3XTFg/zxg28c+9CBNfBkGtOllvC5Ay9K40uU6BHXTZL3mXit3BlKUOkF79NVvjZaesRonJdIWnA==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ solid-js: '>=1.9.7'
+
'@tanstack/solid-store@0.7.7':
resolution: {integrity: sha512-DnEZbqQ+pg68BguHz17VFukfp+6JaTk8nE2MhdVliU8bhsOFlTMsmVHp/4gMoQ1AkmAOMFiBsSliROCaaeJzvg==}
peerDependencies:
@@ -15300,6 +15395,34 @@ snapshots:
transitivePeerDependencies:
- csstype
+ '@tanstack/devtools-ui@0.4.0(csstype@3.1.3)(solid-js@1.9.9)':
+ dependencies:
+ clsx: 2.1.1
+ goober: 2.1.16(csstype@3.1.3)
+ solid-js: 1.9.9
+ transitivePeerDependencies:
+ - csstype
+
+ '@tanstack/devtools-utils@0.0.3(@types/react@19.1.6)(csstype@3.1.3)(react@19.1.0)(solid-js@1.9.9)':
+ dependencies:
+ '@tanstack/devtools-ui': 0.3.5(csstype@3.1.3)(solid-js@1.9.9)
+ optionalDependencies:
+ '@types/react': 19.1.6
+ react: 19.1.0
+ solid-js: 1.9.9
+ transitivePeerDependencies:
+ - csstype
+
+ '@tanstack/devtools-utils@0.0.4(@types/react@19.1.6)(csstype@3.1.3)(react@19.1.0)(solid-js@1.9.9)':
+ dependencies:
+ '@tanstack/devtools-ui': 0.4.0(csstype@3.1.3)(solid-js@1.9.9)
+ optionalDependencies:
+ '@types/react': 19.1.6
+ react: 19.1.0
+ solid-js: 1.9.9
+ transitivePeerDependencies:
+ - csstype
+
'@tanstack/devtools@0.6.14(csstype@3.1.3)(solid-js@1.9.9)':
dependencies:
'@solid-primitives/keyboard': 1.3.3(solid-js@1.9.9)
@@ -15313,6 +15436,19 @@ snapshots:
- csstype
- utf-8-validate
+ '@tanstack/devtools@0.6.16(csstype@3.1.3)(solid-js@1.9.9)':
+ dependencies:
+ '@solid-primitives/keyboard': 1.3.3(solid-js@1.9.9)
+ '@tanstack/devtools-event-bus': 0.3.2
+ '@tanstack/devtools-ui': 0.4.0(csstype@3.1.3)(solid-js@1.9.9)
+ clsx: 2.1.1
+ goober: 2.1.16(csstype@3.1.3)
+ solid-js: 1.9.9
+ transitivePeerDependencies:
+ - bufferutil
+ - csstype
+ - utf-8-validate
+
'@tanstack/directive-functions-plugin@1.131.2(vite@7.1.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.4.0)(sass@1.90.0)(sugarss@5.0.1(postcss@8.5.6))(terser@5.43.1)(tsx@4.19.4)(yaml@2.8.0))':
dependencies:
'@babel/code-frame': 7.27.1
@@ -15570,6 +15706,15 @@ snapshots:
- supports-color
- vite
+ '@tanstack/solid-devtools@0.7.2(csstype@3.1.3)(solid-js@1.9.9)':
+ dependencies:
+ '@tanstack/devtools': 0.6.16(csstype@3.1.3)(solid-js@1.9.9)
+ solid-js: 1.9.9
+ transitivePeerDependencies:
+ - bufferutil
+ - csstype
+ - utf-8-validate
+
'@tanstack/solid-store@0.7.7(solid-js@1.9.9)':
dependencies:
'@tanstack/store': 0.7.7