Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
3daff38
initial setup -- duplicated + package.json edited
theVedanta Dec 1, 2025
0e40281
simple preact updations
theVedanta Dec 15, 2025
722e05b
missed a React.ReactNode
theVedanta Dec 15, 2025
78cf64a
testing grunt work (preact library + other small issues + ErrorBounda…
theVedanta Dec 17, 2025
a9c5c75
missed a few
theVedanta Dec 17, 2025
8cc6ed5
Adds ErrorBoundary (from react-error-boundary, but scaled down for pr…
theVedanta Dec 26, 2025
088795b
useSuspenseQueries left -- removed the useQuery.promise tests
theVedanta Dec 27, 2025
0f5bdbc
forgot the console logs
theVedanta Dec 27, 2025
6d23454
useSuspenseQueries 2 resolved; tests done
theVedanta Dec 27, 2025
60502ad
Merge branch 'main' into pr/9935
TkDodo Dec 28, 2025
f2f73f9
Merge branch 'main' into preact-adapter
TkDodo Dec 28, 2025
460919e
ci: apply automated fixes
autofix-ci[bot] Dec 28, 2025
1a3afe6
Merge branch 'main' into preact-adapter
TkDodo Dec 28, 2025
05af042
fix: example
TkDodo Dec 28, 2025
4d5a0f0
fix: configs should be symlinks
TkDodo Dec 28, 2025
f451435
fix: sync versions for npm-run-all2
TkDodo Dec 28, 2025
b2e95fd
ref: re-sync runall2
TkDodo Dec 28, 2025
34f0262
ref: go back to 5.0.0
TkDodo Dec 28, 2025
4e366c4
ref: remove changelog
TkDodo Dec 28, 2025
3c6b541
react-query -> preact-query
TkDodo Dec 28, 2025
66605b1
remove use client directive + added the useSyncExternalStore (decoupl…
theVedanta Dec 28, 2025
c069be8
Merge branch 'preact-adapter' of https://github.com/theVedanta/query …
theVedanta Dec 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions examples/preact/simple/.gitignore
Original file line number Diff line number Diff line change
@@ -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?
15 changes: 15 additions & 0 deletions examples/preact/simple/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# `create-preact`

<h2 align="center">
<img height="256" width="256" src="./src/assets/preact.svg">
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

Add alt text to the image for accessibility.

The <img> tag is missing the alt attribute, which is required for screen readers and accessibility compliance.

🔎 Proposed fix
-  <img height="256" width="256" src="./src/assets/preact.svg">
+  <img height="256" width="256" src="./src/assets/preact.svg" alt="Preact logo">
📝 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
<img height="256" width="256" src="./src/assets/preact.svg">
<img height="256" width="256" src="./src/assets/preact.svg" alt="Preact logo">
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

4-4: Images should have alternate text (alt text)

(MD045, no-alt-text)

🤖 Prompt for AI Agents
In examples/preact/simple/README.md around line 4, the <img> tag lacks an alt
attribute; add a meaningful alt text (e.g., alt="Preact logo" or an appropriate
descriptive string) to the tag to satisfy accessibility requirements and screen
readers by editing the image element to include the alt attribute.

</h2>

<h3 align="center">Get started using Preact and Vite!</h3>

## Getting Started

- `pnpm dev` - Starts a dev server at http://localhost:5173/

- `pnpm build` - Builds for production, emitting to `dist/`

- `pnpm preview` - Starts a server at http://localhost:4173/ to test production build locally
14 changes: 14 additions & 0 deletions examples/preact/simple/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="light dark" />
<title>Vite + Preact</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
23 changes: 23 additions & 0 deletions examples/preact/simple/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@tanstack/preact-query": "workspace:^",
"preact": "^10.26.9"
},
"devDependencies": {
"@preact/preset-vite": "^2.10.2",
"eslint": "^9.36.0",
"eslint-config-preact": "^2.0.0",
"typescript": "^5.9.3",
"vite": "^7.0.4"
},
"eslintConfig": {
"extends": "preact"
}
}
15 changes: 15 additions & 0 deletions examples/preact/simple/public/vite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions examples/preact/simple/src/assets/preact.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 45 additions & 0 deletions examples/preact/simple/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { render } from 'preact'
import {
QueryClient,
QueryClientProvider,
useQuery,
} from '@tanstack/preact-query'

const queryClient = new QueryClient()

export function App() {
return (
<QueryClientProvider client={queryClient}>
<Example />
</QueryClientProvider>
)
}

const Example = () => {
const { isPending, error, data, isFetching } = useQuery({
queryKey: ['repoData'],
queryFn: async () => {
const response = await fetch(
'https://api.github.com/repos/TanStack/query',
)
return await response.json()
},
Comment on lines +21 to +26
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 | 🟠 Major

Add response status validation.

The fetch call doesn't check response.ok, so non-2xx HTTP responses will still attempt JSON parsing and may not be caught properly as errors. This could lead to confusing error messages or unhandled failures.

🔎 Proposed fix
     queryFn: async () => {
       const response = await fetch(
         'https://api.github.com/repos/TanStack/query',
       )
+      if (!response.ok) {
+        throw new Error(`HTTP error! status: ${response.status}`)
+      }
       return await response.json()
     },
📝 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
queryFn: async () => {
const response = await fetch(
'https://api.github.com/repos/TanStack/query',
)
return await response.json()
},
queryFn: async () => {
const response = await fetch(
'https://api.github.com/repos/TanStack/query',
)
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
return await response.json()
},
🤖 Prompt for AI Agents
In examples/preact/simple/src/index.tsx around lines 20 to 25, the fetch
response is parsed without validating HTTP status; update the queryFn to check
response.ok before calling response.json(), and if not ok throw an error
containing the response status and statusText (optionally including the response
body text/json) so non-2xx responses are surfaced as errors to the caller.

})

if (isPending) return 'Loading...'

if (error !== null) return 'An error has occurred: ' + error.message

return (
<div>
<h1>{data.full_name}</h1>
<p>{data.description}</p>
<strong>👀 {data.subscribers_count}</strong>{' '}
<strong>✨ {data.stargazers_count}</strong>{' '}
<strong>🍴 {data.forks_count}</strong>
<div>{isFetching ? 'Updating...' : ''}</div>
</div>
)
}

render(<App />, document.getElementById('app'))
82 changes: 82 additions & 0 deletions examples/preact/simple/src/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;

color: #222;
background-color: #ffffff;

font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}

body {
margin: 0;
display: flex;
align-items: center;
min-height: 100vh;
}

#app {
max-width: 1280px;
margin: 0 auto;
text-align: center;
}

img {
margin-bottom: 1.5rem;
}

img:hover {
filter: drop-shadow(0 0 2em #673ab8aa);
}

section {
margin-top: 5rem;
display: grid;
grid-template-columns: repeat(3, 1fr);
column-gap: 1.5rem;
}

.resource {
padding: 0.75rem 1.5rem;
border-radius: 0.5rem;
text-align: left;
text-decoration: none;
color: #222;
background-color: #f1f1f1;
border: 1px solid transparent;
}

.resource:hover {
border: 1px solid #000;
box-shadow: 0 25px 50px -12px #673ab888;
}

@media (max-width: 639px) {
#app {
margin: 2rem;
}
section {
margin-top: 5rem;
grid-template-columns: 1fr;
row-gap: 1rem;
}
}

@media (prefers-color-scheme: dark) {
:root {
color: #ccc;
background-color: #1a1a1a;
}
.resource {
color: #ccc;
background-color: #161616;
}
.resource:hover {
border: 1px solid #bbb;
}
}
20 changes: 20 additions & 0 deletions examples/preact/simple/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"noEmit": true,
"allowJs": true,
"checkJs": true,

/* Preact Config */
"jsx": "react-jsx",
"jsxImportSource": "preact",
"skipLibCheck": true,
"paths": {
"react": ["./node_modules/preact/compat/"],
"react-dom": ["./node_modules/preact/compat/"]
}
},
"include": ["node_modules/vite/client.d.ts", "**/*"]
}
7 changes: 7 additions & 0 deletions examples/preact/simple/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import preact from '@preact/preset-vite'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [preact()],
})
Empty file.
48 changes: 48 additions & 0 deletions packages/preact-query/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<img src="https://static.scarf.sh/a.png?x-pxid=be2d8a11-9712-4c1d-9963-580b2d4fb133" />

![TanStack Query Header](https://github.com/TanStack/query/raw/main/media/repo-header.png)
Comment on lines +1 to +3
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

Add alt text to images.

The tracking pixel (line 1) and header image (line 3) are missing alt text, which violates accessibility guidelines.

🔎 Proposed fix
-<img src="https://static.scarf.sh/a.png?x-pxid=be2d8a11-9712-4c1d-9963-580b2d4fb133" />
+<img alt="Scarf analytics" src="https://static.scarf.sh/a.png?x-pxid=be2d8a11-9712-4c1d-9963-580b2d4fb133" />

 ![TanStack Query Header](https://github.com/TanStack/query/raw/main/media/repo-header.png)
📝 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
<img src="https://static.scarf.sh/a.png?x-pxid=be2d8a11-9712-4c1d-9963-580b2d4fb133" />
![TanStack Query Header](https://github.com/TanStack/query/raw/main/media/repo-header.png)
<img alt="Scarf analytics" src="https://static.scarf.sh/a.png?x-pxid=be2d8a11-9712-4c1d-9963-580b2d4fb133" />
![TanStack Query Header](https://github.com/TanStack/query/raw/main/media/repo-header.png)
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

1-1: Images should have alternate text (alt text)

(MD045, no-alt-text)

🤖 Prompt for AI Agents
In packages/preact-query/README.md lines 1 to 3, both image tags lack alt
attributes; add meaningful alt text to the tracking pixel and the header image
(e.g., alt="" for decorative tracking pixel or alt="Tracking pixel" if needed,
and alt="TanStack Query header" or similar for the header) by including an
appropriate alt attribute on each <img> (or Markdown image) tag to satisfy
accessibility guidelines.


Hooks for fetching, caching and updating asynchronous data in React
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 the framework name in the description.

The description says "React" but this is the Preact adapter. Update to reflect Preact.

🔎 Proposed fix
-Hooks for fetching, caching and updating asynchronous data in React
+Hooks for fetching, caching and updating asynchronous data in Preact
📝 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
Hooks for fetching, caching and updating asynchronous data in React
Hooks for fetching, caching and updating asynchronous data in Preact
🤖 Prompt for AI Agents
In packages/preact-query/README.md around line 5, the one-line description
incorrectly references "React" even though this package is the Preact adapter;
update the sentence to say "Preact" instead of "React" so the description
accurately reflects the framework used.


<a href="https://twitter.com/intent/tweet?button_hashtag=TanStack" target="\_parent">
<img alt="#TanStack" src="https://img.shields.io/twitter/url?color=%2308a0e9&label=%23TanStack&style=social&url=https%3A%2F%2Ftwitter.com%2Fintent%2Ftweet%3Fbutton_hashtag%3DTanStack">
</a><a href="https://discord.com/invite/WrRKjPJ" target="\_parent">
<img alt="" src="https://img.shields.io/badge/Discord-TanStack-%235865F2" />
</a><a href="https://github.com/TanStack/query/actions?query=workflow%3A%22preact-query+tests%22">
<img src="https://github.com/TanStack/query/workflows/preact-query%20tests/badge.svg" />
</a><a href="https://www.npmjs.com/package/@tanstack/query-core" target="\_parent">
<img alt="" src="https://img.shields.io/npm/dm/@tanstack/query-core.svg" />
</a><a href="https://bundlejs.com/?q=%40tanstack%2Fpreact-query&config=%7B%22esbuild%22%3A%7B%22external%22%3A%5B%22react%22%2C%22react-dom%22%5D%7D%7D&badge=" target="\_parent">
<img alt="" src="https://deno.bundlejs.com/?q=@tanstack/preact-query&config={%22esbuild%22:{%22external%22:[%22react%22,%22react-dom%22]}}&badge=detailed" />
Comment on lines +15 to +16
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 bundle badge external dependencies configuration.

The bundlejs badge configuration incorrectly specifies react and react-dom as external dependencies. For Preact, these should be preact and related Preact packages.

🔎 Proposed fix
-<a href="https://bundlejs.com/?q=%40tanstack%2Fpreact-query&config=%7B%22esbuild%22%3A%7B%22external%22%3A%5B%22react%22%2C%22react-dom%22%5D%7D%7D&badge=" target="\_parent">
-  <img alt="" src="https://deno.bundlejs.com/?q=@tanstack/preact-query&config={%22esbuild%22:{%22external%22:[%22react%22,%22react-dom%22]}}&badge=detailed" />
+<a href="https://bundlejs.com/?q=%40tanstack%2Fpreact-query&config=%7B%22esbuild%22%3A%7B%22external%22%3A%5B%22preact%22%5D%7D%7D&badge=" target="\_parent">
+  <img alt="Bundle size badge" src="https://deno.bundlejs.com/?q=@tanstack/preact-query&config={%22esbuild%22:{%22external%22:[%22preact%22]}}&badge=detailed" />

Note: This also adds missing alt text per the earlier fix.

📝 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
</a><a href="https://bundlejs.com/?q=%40tanstack%2Fpreact-query&config=%7B%22esbuild%22%3A%7B%22external%22%3A%5B%22react%22%2C%22react-dom%22%5D%7D%7D&badge=" target="\_parent">
<img alt="" src="https://deno.bundlejs.com/?q=@tanstack/preact-query&config={%22esbuild%22:{%22external%22:[%22react%22,%22react-dom%22]}}&badge=detailed" />
</a><a href="https://bundlejs.com/?q=%40tanstack%2Fpreact-query&config=%7B%22esbuild%22%3A%7B%22external%22%3A%5B%22preact%22%5D%7D%7D&badge=" target="\_parent">
<img alt="Bundle size badge" src="https://deno.bundlejs.com/?q=@tanstack/preact-query&config={%22esbuild%22:{%22external%22:[%22preact%22]}}&badge=detailed" />
🤖 Prompt for AI Agents
In packages/preact-query/README.md around lines 15 to 16, the bundlejs badge URL
lists "react" and "react-dom" as external dependencies which is incorrect for
this Preact package; update the badge query/config to mark Preact packages
(e.g., "preact" and other relevant Preact packages used by the library such as
"preact/hooks" or "preact/jsx-runtime") as externals instead of react/react-dom,
and also add a meaningful alt attribute to the <img> tag (e.g., "Bundle size for
@tanstack/preact-query") to replace the empty alt text.

</a><a href="#badge">
<img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
</a><a href="https://github.com/TanStack/query/discussions">
<img alt="Join the discussion on Github" src="https://img.shields.io/badge/Github%20Discussions%20%26%20Support-Chat%20now!-blue" />
</a><a href="https://bestofjs.org/projects/tanstack-query"><img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=TanStack%2Fquery%26since=daily" /></a><a href="https://github.com/TanStack/query/" target="\_parent">
<img alt="" src="https://img.shields.io/github/stars/TanStack/query.svg?style=social&label=Star" />
</a><a href="https://twitter.com/tannerlinsley" target="\_parent">
<img alt="" src="https://img.shields.io/twitter/follow/tannerlinsley.svg?style=social&label=Follow" />
</a> <a href="https://gitpod.io/from-referrer/">
<img src="https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod" alt="Gitpod Ready-to-Code"/>
</a>

Enjoy this library? Try the entire [TanStack](https://tanstack.com)! [TanStack Table](https://github.com/TanStack/table), [TanStack Router](https://github.com/tanstack/router), [TanStack Virtual](https://github.com/tanstack/virtual), [React Charts](https://github.com/TanStack/react-charts), [React Ranger](https://github.com/TanStack/ranger)

## Visit [tanstack.com/query](https://tanstack.com/query) for docs, guides, API and more!

## Quick Features

- Transport/protocol/backend agnostic data fetching (REST, GraphQL, promises, whatever!)
- Auto Caching + Refetching (stale-while-revalidate, Window Refocus, Polling/Realtime)
- Parallel + Dependent Queries
- Mutations + Reactive Query Refetching
- Multi-layer Cache + Automatic Garbage Collection
- Paginated + Cursor-based Queries
- Load-More + Infinite Scroll Queries w/ Scroll Recovery
- Request Cancellation
- [React Suspense](https://react.dev/reference/react/Suspense) + Fetch-As-You-Render Query Prefetching
- Dedicated Devtools

### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/)

<!-- Use the force, Luke -->
38 changes: 38 additions & 0 deletions packages/preact-query/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// @ts-check

import rootConfig from './root.eslint.config.js'
// @ts-ignore: no types for eslint-config-preact
import preact from 'eslint-config-preact'
import tseslint from 'typescript-eslint'

export default [
...rootConfig,
...preact,
{
files: ['**/*.{ts,tsx}'],
languageOptions: {
parser: tseslint.parser,
parserOptions: {
project: true,
},
},
plugins: {
'typescript-eslint': tseslint.plugin,
},
rules: {
// Disable base rule to prevent overload false positives
'no-redeclare': 'off',
'no-duplicate-imports': 'off',
// TS-aware version handles overloads correctly
'@typescript-eslint/no-redeclare': 'error',
'@typescript-eslint/no-duplicate-imports': 'error',
},
},
{
files: ['**/__tests__/**'],
rules: {
'@eslint-react/dom/no-missing-button-type': 'off',
'@typescript-eslint/no-unnecessary-condition': 'off',
},
},
]
Loading