Skip to content

Comments

Add preact query devtools#10119

Open
JoviDeCroock wants to merge 6 commits intoTanStack:mainfrom
JoviDeCroock:add-preact-devtools-package
Open

Add preact query devtools#10119
JoviDeCroock wants to merge 6 commits intoTanStack:mainfrom
JoviDeCroock:add-preact-devtools-package

Conversation

@JoviDeCroock
Copy link

@JoviDeCroock JoviDeCroock commented Feb 12, 2026

🎯 Changes

This adds the preact-query devtools package similar to the existing vue/solid/svelte/react ones

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

This is the initial release of the package.

Summary by CodeRabbit

  • New Features

    • Introduced a Preact Query Devtools package with configurable Devtools and Panel components; devtools are enabled only in development builds and are no-ops in production.
    • Added floating mode, configurable button/position, initial open state, hide-disabled-queries toggle, error handling and theme options.
  • Documentation

    • Added comprehensive docs covering installation, import, usage, floating mode, and all configuration options.
  • Tests

    • Added test setup to improve devtools test reliability.

@changeset-bot
Copy link

changeset-bot bot commented Feb 12, 2026

⚠️ No Changeset found

Latest commit: e303464

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions github-actions bot added the documentation Improvements or additions to documentation label Feb 12, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

📝 Walkthrough

Walkthrough

Adds a new @tanstack/preact-query-devtools package: Preact-specific devtools components and panel, build/test/lint/ts configs, docs, test setup, and development-only export guards with production no-op stubs and modern/legacy build targets.

Changes

Cohort / File(s) Summary
Documentation
docs/config.json, docs/framework/preact/devtools.md
Added Getting Started entry and a new devtools guide with install, usage, options, and floating mode examples.
Package manifest
packages/preact-query-devtools/package.json, packages/preact-query-devtools/.attw.json
New package metadata, scripts, exports map (modern/legacy), workspace deps, and attw ignore rule.
Source: components & exports
packages/preact-query-devtools/src/PreactQueryDevtools.tsx, packages/preact-query-devtools/src/PreactQueryDevtoolsPanel.tsx, packages/preact-query-devtools/src/index.ts, packages/preact-query-devtools/src/production.ts
New Preact wrapper components and panel, public option interfaces, prop-to-devtools syncing via effects, mount/unmount lifecycle, and dev/prod guarded exports.
Build & bundler configs
packages/preact-query-devtools/root.tsup.config.js, packages/preact-query-devtools/tsup.config.ts, packages/preact-query-devtools/vite.config.ts
Added tsup modern/legacy builders and Vite config (Preact preset, resolve conditions, vitest/test coverage config).
TypeScript configs
packages/preact-query-devtools/tsconfig.json, packages/preact-query-devtools/tsconfig.legacy.json, packages/preact-query-devtools/tsconfig.prod.json
New TS project configs: JSX runtime set to Preact, outputs, and project references for prod/legacy builds.
Linting
packages/preact-query-devtools/eslint.config.js, packages/preact-query-devtools/root.eslint.config.js
Package and root ESLint configs: extend shared rules, TS-aware overrides, cspell dictionary, and vitest test rules.
Testing setup
packages/preact-query-devtools/test-setup.ts
Vitest/testing-library setup: DOM cleanup and wrapping notifyManager.notify with act.

Sequence Diagram(s)

sequenceDiagram
    participant App as AppComponent
    participant PDev as PreactQueryDevtools
    participant QC as QueryClient
    participant TD as TanstackQueryDevtools
    participant DOM as DOMContainer

    App->>PDev: Mount(props)
    PDev->>QC: useQueryClient(props.client)
    QC-->>PDev: client
    PDev->>TD: create Devtools instance (client, config)
    TD-->>PDev: instance ready
    PDev->>DOM: create container div
    TD->>DOM: mount UI into container

    App->>PDev: Update props (theme, positions, etc.)
    PDev->>TD: sync prop changes
    TD->>DOM: re-render/reflect updates

    App->>PDev: Unmount
    PDev->>TD: unmount & cleanup
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

package: query-devtools

Suggested reviewers

  • TkDodo

Poem

🐇 Hopping in with a tiny cheer,
Preact devtools now appear,
Docs and builds all set to play,
Props and mounts dance through the day,
A rabbit claps: “Nice work, hooray!” 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add preact query devtools' clearly and concisely describes the main change: adding a new preact-query devtools package.
Description check ✅ Passed The PR description follows the template with completed checklist items and acknowledges the initial release, though the Release Impact section lacks specificity about changesets.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@JoviDeCroock JoviDeCroock force-pushed the add-preact-devtools-package branch from 359aade to 1e3d386 Compare February 12, 2026 06:06
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@packages/preact-query-devtools/src/PreactQueryDevtools.tsx`:
- Line 1: The import members are not alphabetically ordered; update the named
import from 'preact/hooks' so the specifiers are sorted alphabetically (e.g.,
ensure useEffect comes before useRef and useState) in the statement that
currently imports useRef, useState, useEffect to satisfy ESLint for the
PreactQueryDevtools component.
- Around line 33-38: The JSDoc for the prop errorTypes is wrong (copied from
styleNonce); update the comment above the errorTypes property (type
Array<DevtoolsErrorType>) to describe what errorTypes does — e.g., that it
accepts an array of DevtoolsErrorType values to filter or categorize which error
kinds the devtools should display or highlight (mention valid enum/members if
applicable), and clarify default behavior when the array is empty or omitted;
edit the JSDoc near the errorTypes declaration to reflect this intent.

In `@packages/preact-query-devtools/vite.config.ts`:
- Around line 1-4: The import order violates ESLint: move the packageJson import
before the type import from 'vite' so that "import packageJson from
'./package.json'" appears above "import type { UserConfig as ViteUserConfig }
from 'vite'"; update the top of the file to list imports as preact, packageJson,
then the vite type import (keeping existing symbols preact, defineConfig,
ViteUserConfig, and packageJson intact).
🧹 Nitpick comments (1)
packages/preact-query-devtools/root.eslint.config.js (1)

20-40: Cspell word list contains terms irrelevant to the Preact package.

Words like solidjs, vue-demi, ɵkind, and ɵproviders appear to be copy-pasted from another package's config. They're harmless but add noise — consider trimming to only Preact-relevant terms.

@@ -0,0 +1,131 @@
import { useRef, useState, useEffect } from 'preact/hooks'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Sort import members alphabetically to satisfy ESLint.

ESLint reports that useEffect should come before useRef in the import declaration.

Proposed fix
-import { useRef, useState, useEffect } from 'preact/hooks'
+import { useEffect, useRef, useState } from 'preact/hooks'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { useRef, useState, useEffect } from 'preact/hooks'
import { useEffect, useRef, useState } from 'preact/hooks'
🧰 Tools
🪛 ESLint

[error] 1-1: Member 'useEffect' of the import declaration should be sorted alphabetically.

(sort-imports)

🤖 Prompt for AI Agents
In `@packages/preact-query-devtools/src/PreactQueryDevtools.tsx` at line 1, The
import members are not alphabetically ordered; update the named import from
'preact/hooks' so the specifiers are sorted alphabetically (e.g., ensure
useEffect comes before useRef and useState) in the statement that currently
imports useRef, useState, useEffect to satisfy ESLint for the
PreactQueryDevtools component.

Comment on lines 33 to 38
/**
* Use this to pass a nonce to the style tag that is added to the document
* head. This is useful if you are using a Content Security Policy (CSP)
* nonce to allow inline styles.
*/
errorTypes?: Array<DevtoolsErrorType>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Copy-paste error in JSDoc for errorTypes.

The docstring for errorTypes is identical to the one for styleNonce ("Use this to pass a nonce to the style tag…"). It should describe the error types functionality instead.

Proposed fix
   /**
-   * Use this to pass a nonce to the style tag that is added to the document
-   * head. This is useful if you are using a Content Security Policy (CSP)
-   * nonce to allow inline styles.
+   * Use this to provide custom error type handlers for the devtools panel.
    */
   errorTypes?: Array<DevtoolsErrorType>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Use this to pass a nonce to the style tag that is added to the document
* head. This is useful if you are using a Content Security Policy (CSP)
* nonce to allow inline styles.
*/
errorTypes?: Array<DevtoolsErrorType>
/**
* Use this to provide custom error type handlers for the devtools panel.
*/
errorTypes?: Array<DevtoolsErrorType>
🤖 Prompt for AI Agents
In `@packages/preact-query-devtools/src/PreactQueryDevtools.tsx` around lines 33 -
38, The JSDoc for the prop errorTypes is wrong (copied from styleNonce); update
the comment above the errorTypes property (type Array<DevtoolsErrorType>) to
describe what errorTypes does — e.g., that it accepts an array of
DevtoolsErrorType values to filter or categorize which error kinds the devtools
should display or highlight (mention valid enum/members if applicable), and
clarify default behavior when the array is empty or omitted; edit the JSDoc near
the errorTypes declaration to reflect this intent.

Comment on lines +1 to +4
import preact from '@preact/preset-vite'
import { defineConfig } from 'vitest/config'
import type { UserConfig as ViteUserConfig } from 'vite'
import packageJson from './package.json'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix import order to satisfy ESLint.

ESLint flags that the ./package.json import should occur before the type import of vite. This is reported as an error and may fail CI.

🔧 Proposed fix
 import preact from '@preact/preset-vite'
 import { defineConfig } from 'vitest/config'
-import type { UserConfig as ViteUserConfig } from 'vite'
 import packageJson from './package.json'
+import type { UserConfig as ViteUserConfig } from 'vite'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import preact from '@preact/preset-vite'
import { defineConfig } from 'vitest/config'
import type { UserConfig as ViteUserConfig } from 'vite'
import packageJson from './package.json'
import preact from '@preact/preset-vite'
import { defineConfig } from 'vitest/config'
import packageJson from './package.json'
import type { UserConfig as ViteUserConfig } from 'vite'
🧰 Tools
🪛 ESLint

[error] 4-4: ./package.json import should occur before type import of vite

(import/order)

🤖 Prompt for AI Agents
In `@packages/preact-query-devtools/vite.config.ts` around lines 1 - 4, The import
order violates ESLint: move the packageJson import before the type import from
'vite' so that "import packageJson from './package.json'" appears above "import
type { UserConfig as ViteUserConfig } from 'vite'"; update the top of the file
to list imports as preact, packageJson, then the vite type import (keeping
existing symbols preact, defineConfig, ViteUserConfig, and packageJson intact).

@JoviDeCroock JoviDeCroock force-pushed the add-preact-devtools-package branch from 1e3d386 to d631591 Compare February 12, 2026 06:13
@JoviDeCroock JoviDeCroock force-pushed the add-preact-devtools-package branch from d631591 to fd22045 Compare February 12, 2026 06:14
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@docs/framework/preact/devtools.md`:
- Around line 69-87: The Options docs omit the hideDisabledQueries and theme
props present on the DevtoolsOptions interface in PreactQueryDevtools.tsx;
update this Options section to document both: add a `hideDisabledQueries?:
boolean` entry describing that it hides queries in the UI that are disabled, and
add a `theme?: "light" | "dark" | string` (or whatever variants the
implementation accepts) entry describing theme selection and default. Reference
the DevtoolsOptions interface/props in PreactQueryDevtools.tsx to ensure wording
and default values match the implementation.

In `@packages/preact-query-devtools/src/PreactQueryDevtoolsPanel.tsx`:
- Line 1: The import list in PreactQueryDevtoolsPanel (the import from
'preact/hooks') is not alphabetized; reorder the imported members so they are
alphabetical (useEffect, useRef, useState) in the import declaration to satisfy
ESLint (update the import that currently declares useRef, useState, useEffect).
🧹 Nitpick comments (1)
packages/preact-query-devtools/src/index.ts (1)

18-18: Export DevtoolsOptions type alongside DevtoolsPanelOptions.

DevtoolsPanelOptions is re-exported from the index, but DevtoolsOptions (defined in PreactQueryDevtools.tsx) is not. Consumers typing props for PreactQueryDevtools must import from the component file directly instead of the main entry point, creating an asymmetric and less discoverable API.

Suggested fix
 export type DevtoolsPanelOptions = DevtoolsPanel.DevtoolsPanelOptions
+export type DevtoolsOptions = Devtools.DevtoolsOptions

Comment on lines +69 to +87
### Options

- `initialIsOpen: boolean`
- Set this `true` if you want the dev tools to default to being open
- `buttonPosition?: "top-left" | "top-right" | "bottom-left" | "bottom-right"`
- Defaults to `bottom-right`
- The position of the Preact Query logo to open and close the devtools panel
- `position?: "top" | "bottom" | "left" | "right"`
- Defaults to `bottom`
- The position of the Preact Query devtools panel
- `client?: QueryClient`,
- Use this to use a custom QueryClient. Otherwise, the one from the nearest context will be used.
- `errorTypes?: { name: string; initializer: (query: Query) => TError}`
- Use this to predefine some errors that can be triggered on your queries. Initializer will be called (with the specific query) when that error is toggled on from the UI. It must return an Error.
- `styleNonce?: string`
- Use this to pass a nonce to the style tag that is added to the document head. This is useful if you are using a Content Security Policy (CSP) nonce to allow inline styles.
- `shadowDOMTarget?: ShadowRoot`
- Default behavior will apply the devtool's styles to the head tag within the DOM.
- Use this to pass a shadow DOM target to the devtools so that the styles will be applied within the shadow DOM instead of within the head tag in the light DOM.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Documentation is missing hideDisabledQueries and theme options.

The DevtoolsOptions interface in PreactQueryDevtools.tsx includes hideDisabledQueries and theme props, but this Options section doesn't list them. Consider adding them for completeness.

🤖 Prompt for AI Agents
In `@docs/framework/preact/devtools.md` around lines 69 - 87, The Options docs
omit the hideDisabledQueries and theme props present on the DevtoolsOptions
interface in PreactQueryDevtools.tsx; update this Options section to document
both: add a `hideDisabledQueries?: boolean` entry describing that it hides
queries in the UI that are disabled, and add a `theme?: "light" | "dark" |
string` (or whatever variants the implementation accepts) entry describing theme
selection and default. Reference the DevtoolsOptions interface/props in
PreactQueryDevtools.tsx to ensure wording and default values match the
implementation.

@@ -0,0 +1,110 @@
import { useRef, useState, useEffect } from 'preact/hooks'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Sort import members alphabetically to satisfy ESLint.

ESLint reports that useEffect should come before useRef in the import declaration.

Proposed fix
-import { useRef, useState, useEffect } from 'preact/hooks'
+import { useEffect, useRef, useState } from 'preact/hooks'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { useRef, useState, useEffect } from 'preact/hooks'
import { useEffect, useRef, useState } from 'preact/hooks'
🧰 Tools
🪛 ESLint

[error] 1-1: Member 'useEffect' of the import declaration should be sorted alphabetically.

(sort-imports)

🤖 Prompt for AI Agents
In `@packages/preact-query-devtools/src/PreactQueryDevtoolsPanel.tsx` at line 1,
The import list in PreactQueryDevtoolsPanel (the import from 'preact/hooks') is
not alphabetized; reorder the imported members so they are alphabetical
(useEffect, useRef, useState) in the import declaration to satisfy ESLint
(update the import that currently declares useRef, useState, useEffect).

@theVedanta
Copy link
Contributor

Can we have some of those simple tests that just test open/close state? Like is done in other devtool packages

Copy link
Contributor

@theVedanta theVedanta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

running workflows

@theVedanta
Copy link
Contributor

This LGTM! Just addressing those two comments about docs and tests can take us to merging.

@JoviDeCroock
Copy link
Author

@theVedanta Most others just have stub tests https://github.com/TanStack/query/blob/main/packages/react-query-devtools/src/__tests__/devtools.test.tsx#L5 I would prefer not to add those. The devtools packages are largely untested and adding a specfic one for that production stuff feels a bit overdone

@theVedanta
Copy link
Contributor

@theVedanta Most others just have stub tests https://github.com/TanStack/query/blob/main/packages/react-query-devtools/src/__tests__/devtools.test.tsx#L5 I would prefer not to add those. The devtools packages are largely untested and adding a specfic one for that production stuff feels a bit overdone

Understandable!

@nx-cloud
Copy link

nx-cloud bot commented Feb 23, 2026

🤖 Nx Cloud AI Fix Eligible

An automatically generated fix could have helped fix failing tasks for this run, but Self-healing CI is disabled for this workspace. Visit workspace settings to enable it and get automatic fixes in future runs.

To disable these notifications, a workspace admin can disable them in workspace settings.


View your CI Pipeline Execution ↗ for commit a9eb1d0

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ❌ Failed 1m View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 8s View ↗

☁️ Nx Cloud last updated this comment at 2026-02-23 06:15:49 UTC

@theVedanta
Copy link
Contributor

Can you get those lockfile errors, please? I don't expect PR / Preview to pass since it's a new package, but the rest would be fine

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/preact-query-devtools/src/PreactQueryDevtools.tsx (1)

113-115: setTheme is called without a guard while setButtonPosition/setPosition both guard against undefined.

theme is optional, so devtools.setTheme(undefined) will fire on every render where theme is not provided. The adjacent effects for buttonPosition and position skip the setter when the prop is absent. If setTheme doesn't treat undefined as "reset to system default", this could cause an unintended override.

♻️ Proposed fix for consistent guard
   useEffect(() => {
-    devtools.setTheme(theme)
+    if (theme) {
+      devtools.setTheme(theme)
+    }
   }, [theme, devtools])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/preact-query-devtools/src/PreactQueryDevtools.tsx` around lines 113
- 115, The useEffect calls devtools.setTheme(theme) without guarding for
undefined; mirror the existing guards used for setButtonPosition and setPosition
by only invoking devtools.setTheme when the incoming prop is defined (e.g.,
check theme !== undefined) inside the useEffect that currently depends on
[theme, devtools]; update the effect that calls devtools.setTheme to skip
calling setTheme when theme is absent so it won't unintentionally override the
devtools theme.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@packages/preact-query-devtools/src/PreactQueryDevtools.tsx`:
- Line 1: The import members are not alphabetized; reorder the named imports in
the import from 'preact/hooks' so they are sorted alphabetically (useEffect,
useRef, useState) to satisfy ESLint — update the import line that currently
lists useRef, useState, useEffect accordingly.

---

Nitpick comments:
In `@packages/preact-query-devtools/src/PreactQueryDevtools.tsx`:
- Around line 113-115: The useEffect calls devtools.setTheme(theme) without
guarding for undefined; mirror the existing guards used for setButtonPosition
and setPosition by only invoking devtools.setTheme when the incoming prop is
defined (e.g., check theme !== undefined) inside the useEffect that currently
depends on [theme, devtools]; update the effect that calls devtools.setTheme to
skip calling setTheme when theme is absent so it won't unintentionally override
the devtools theme.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@packages/preact-query-devtools/src/PreactQueryDevtools.tsx`:
- Line 1: The named imports in PreacQueryDevtools.tsx are not alphabetized which
trips the ESLint sort-imports rule; reorder the specifiers in the import from
'preact/hooks' so they are alphabetically sorted (useEffect, useRef, useState)
to satisfy the linter and keep the import statement consistent.

In `@packages/preact-query-devtools/src/PreactQueryDevtoolsPanel.tsx`:
- Line 1: The import members in the top-level import from 'preact/hooks' are not
alphabetically ordered and violate the sort-imports rule; update the import
statement (the line importing useRef, useState, useEffect) so the imported
identifiers are sorted alphabetically (e.g., useEffect, useRef, useState) to
satisfy ESLint.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants