Release 2026-10-26 09:32
Changes
Features
- angular-query-experimental/injectDevtoolsPanel: add the 'theme' and 'hideDisabledQueries' options (#12316) (8f9dfcb) by @sukvvon
Fix
- angular-query-experimental/withDevtools: forward an unset 'theme' to the devtools so removing it falls back to the theme selected in the devtools Settings menu (#12315) (9e42537) by @sukvvon
- solid-query-devtools: stop defaulting the 'theme' prop to 'system' so the theme chosen in the devtools settings applies when the prop is omitted (#12310) (f232b75) by @sukvvon
- vue-query-devtools: stop defaulting the 'theme' prop to 'system' so the theme chosen in the devtools settings applies when the prop is omitted (#12312) (a282bf8) by @sukvvon
- svelte-query-devtools: stop defaulting the 'theme' prop to 'system' so the theme chosen in the devtools settings applies when the prop is omitted (#12313) (aff30e3) by @sukvvon
- vue-query/queryClient: infer the data and error types of 'getQueryState' from a tagged query key (#11921) (c5de051) by @sukvvon
- examples/lit/pagination: show the error message instead of the stringified error (#12187) (81e6a93) by @sukvvon
- examples/lit/basic: show the error message instead of the stringified error (#12186) (1ed8158) by @sukvvon
- examples/angular/optimistic-updates: throw an 'HttpErrorResponse' from the mock so the failing mutation rolls back in 'onError' (#12173) (35d21b2) by @sukvvon
- examples/angular/infinite-query-with-max-pages: disable the previous page button while fetching the previous page instead of the next page (#12167) (c87c0ea) by @sukvvon
- examples/vue/basic: share the post queries with 'queryOptions' in 'src/api.ts' and mark visited posts from the query cache (#12161) (71fb763) by @sukvvon
- examples/vue/dependent-queries: share the post and author queries with 'queryOptions' in 'src/api.ts' and mark visited posts from the query cache (#12162) (ca7af33) by @sukvvon
- examples/vue/2.7-basic: share the post queries with 'queryOptions' in 'src/api.ts' and mark visited posts from the query cache (#12165) (c83595d) by @sukvvon
- examples/vue/2.6-basic: share the post queries with 'queryOptions' in 'src/api.ts' and mark visited posts from the query cache (#12164) (09cc250) by @sukvvon
- examples/vue/persister: share the post queries and persisters with 'queryOptions' in 'src/api.ts' and mark visited posts from the query cache (#12163) (5824193) by @sukvvon
- examples/vue: show 'Background Updating...' in the posts list and remove the unused 'refetch' (#12139) (5d67aa2) by @sukvvon
- examples/vue/persister: rename the heading from 'Vue Query - Basic' to 'Vue Query - Persister' (#12138) (c00eaa3) by @sukvvon
- examples/vue/simple: remove the stray quote before the error message (#12134) (a4414a7) by @sukvvon
- examples/vue: throw on non-ok 'fetch' responses in the query functions (#12133) (b904739) by @sukvvon
Refactor
- examples/react/nextjs-suspense-streaming: move the data layer into 'services/wait' with a query factory (#12384) (772bd11) by @sukvvon
- examples/{react,solid}/offline: inline 'useMovie' into the 'Detail' component (#12379) (f69600a) by @sukvvon
- examples/solid/{basic,basic-graphql-request}: inline 'createPosts' and 'createPost' that only wrap 'useQuery' (#12378) (c007aaf) by @sukvvon
- examples/react/{basic,basic-graphql-request,eslint-legacy,nextjs,nextjs-suspense-streaming}: inline custom hooks that only wrap 'useQuery' or 'useSuspenseQuery' (#12377) (a52f4e9) by @sukvvon
- examples/angular/{rxjs,devtools-panel}: move the data layer into 'services/{domain}' with a query factory (#12374) (7f86e23) by @sukvvon
- examples/angular/{pagination,infinite-query-with-max-pages}: move the data layer into 'services/projects' with a query factory (#12373) (6b3d091) by @sukvvon
- examples/angular/{auto-refetching,optimistic-updates}: move the data layer into 'services/tasks' with query and mutation factories (#12372) (801ec31) by @sukvvon
- examples/angular/query-options-from-a-service: move the data layer into 'services/posts' with a query factory (#12371) (69ea57b) by @sukvvon
- examples/angular/{basic,basic-persister,router}: move the data layer into 'services/posts' with a query factory (#12370) (7151c20) by @sukvvon
- examples/lit/ssr: move the data layer into 'services/data' with a query factory (#12369) (7ef3775) by @sukvvon
- examples/lit/pagination: move the data layer into 'services/projects' with query and mutation factories (#12368) (15cecf6) by @sukvvon
- examples/lit/basic: move the data layer into 'services/todos' with query and mutation factories (#12367) (55ed711) by @sukvvon
- examples/svelte/playground: move the data layer into 'services/todos' with query and mutation factories (#12366) (a39a5dc) by @sukvvon
- examples/svelte/{auto-refetching,optimistic-updates}: move the data layer into 'services/todos' with query and mutation factories (#12365) (80fdbd4) by @sukvvon
- examples/svelte/ssr: move the data layer into 'services/posts' with a query factory (#12364) (fb2e4c5) by @sukvvon
- examples/svelte/{basic,load-more-infinite-scroll,star-wars}: move the data layer into 'services/{domain}' with a query factory (#12363) (7d9b15a) by @sukvvon
- examples/vue/persister: move the data layer into 'services/posts' with a query factory (#12361) (ff7c510) by @sukvvon
- examples/vue/nuxt3: move the data layer into 'services/posts' with a query factory (#12362) (f4de8a6) by @sukvvon
- examples/vue/{basic,2.6-basic,2.7-basic,dependent-queries,simple}: move the data layer into 'services/{domain}' with a query factory (#12360) (795ded8) by @sukvvon
- examples/solid/{astro,solid-start-streaming}: move the data layer into 'services/{domain}' with a query factory (#12359) (1d95859) by @sukvvon
- examples/solid/offline: move the data layer into 'services/movies' with a query factory (#12358) (cb3c3d5) by @sukvvon
- examples/solid/{basic,basic-graphql-request}: move the data layer into 'services/posts' with a query factory (#12357) (239caf9) by @sukvvon
- examples/react/{nextjs-app-optimistic-updates,nextjs-app-prefetching}: move the data layer into 'services/{domain}' with a query factory (#12356) (516b870) by @sukvvon
- examples/react/{offline,react-router}: move the data layer into 'services/{domain}' with a query factory (#12355) (db886ce) by @sukvvon
- examples/react/{auto-refetching,playground}: move the data layer into 'services/todos' with query and mutation factories (#12354) (dce0498) by @sukvvon
- examples/react/{batching,chat,react-native}: move the data layer into 'services/{domain}' with a query factory (#12353) (f99c6e3) by @sukvvon
- examples/react/{rick-morty,star-wars}: move the data layer into one 'services/{domain}' folder per resource with a query factory (#12352) (88018e5) by @sukvvon
- examples/react: move the data layer of the pagination and infinite query examples into 'services/{domain}' with a query factory (#12351) (1028a29) by @sukvvon
- examples/react: move the data layer of the single-domain examples into 'services/{domain}' with a query factory (#12350) (9aafaa9) by @sukvvon
- examples/react/basic: move the data layer into 'services/posts' with 'api.ts', 'queries.ts', and 'types.ts' and a query factory (#12349) (a777b6b) by @sukvvon
- vue-query/utils: type 'isPlainObject' as 'Record<PropertyKey, unknown>' instead of the 'Object' wrapper type, like 'query-core' (#12343) (4f3dba5) by @sukvvon
- angular-query-experimental/injectQueries: remove the unnecessary 'QueryObserverOptions' assertion and its 'oxlint-disable' comment (#12324) (faa41e9) by @sukvvon
- lit-query/createQueriesController: rename the per-result 'observer' in 'trackResult' to 'resultObserver' to avoid shadowing (#12291) (1117bdd) by @sukvvon
- query-persist-client-core/createPersister: rename the 'filters' option to 'persistFilters' internally to avoid shadowing (#12290) (51e627f) by @sukvvon
- examples/lit/pagination: rename the 'onError' 'context' parameter to 'onMutateResult' (#12195) (64d3b15) by @sukvvon
- examples/lit/pagination: infer the controller types instead of passing generics that repeat the field types (#12185) (8aea733) by @sukvvon
- examples/lit/basic: infer the controller types from the query and mutation functions instead of passing generics (#12184) (45e8a5e) by @sukvvon
- examples/angular: type the mock interceptor events and bodies as 'unknown' instead of 'any' (#12177) (55fa959) by @sukvvon
- examples/angular/{devtools-panel,rxjs,simple}: rename the 'Response' interfaces so they do not shadow the global 'Response' type (#12176) (5106c1b) by @sukvvon
- examples/angular/infinite-query-with-max-pages: type 'nextId' and 'previousId' as 'number | null' to match the mock response (#12175) (c41eb8d) by @sukvvon
- examples/angular/basic-persister: use 'output()' instead of '@output()', remove the unused 'QueryClient', and align the components with the basic example (#12172) (683c869) by @sukvvon
- examples/angular/optimistic-updates: rename the 'onError' 'context' parameter to 'onMutateResult' and prefix the unused ones (#12174) (48b599f) by @sukvvon
- examples/angular/query-options-from-a-service: read the cached post with the service's 'queryKey' instead of an inline key (#12169) (5490375) by @sukvvon
- examples/angular/optimistic-updates: remove the unused 'clearMutation' that created a second add mutation (#12168) (4c9c4cf) by @sukvvon
- examples/angular/basic-persister: make the 'postId' input required and remove the always-true 'enabled' in 'PostComponent' (#12171) (542a134) by @sukvvon
- examples/vue/{basic,dependent-queries,persister,simple}: migrate the components to '<script setup>' (#12144) (243148e) by @sukvvon
- examples/vue: type the 'isVisited' prop with 'PropType' and the visited posts set with 'Set' (#12143) (c76c0ff) by @sukvvon
- examples/vue: declare the example types with 'type' in 'types.ts' instead of 'types.d.ts' (#12141) (d9e7648) by @sukvvon
- examples/vue/persister: remove the commented-out 'staleTime' from the query client config (#12142) (5aefeb7) by @sukvvon
- examples/svelte/playground: edit the 'initialFilter' prop directly in 'TodosList' to remove the 'state_referenced_locally' warning (#12125) (46744e5) by @sukvvon
- examples,docs: use 'TanStack/query' consistently in the GitHub API URLs (#12137) (db22bfc) by @sukvvon
Chore
- deps: update '@typescript-eslint/*' to '^8.72.0' in the catalog and examples (#12388) (06d1705) by @sukvvon
- examples/*/eslint.config: use 'flat/recommended-strict' from '@tanstack/eslint-plugin-query' (#12385) (2b5b641) by @sukvvon
- react-query/{useQuery,useInfiniteQuery}: remove the unused '@eslint-react/no-nested-component-definitions' disable and explain the remaining false positive (#12344) (d7c0418) by @sukvvon
- react-query/{HydrationBoundary,utils}: explain why 'react-hooks-js/refs' and 'react-hooks-js/set-state-in-effect' are disabled (#12342) (aa3e26b) by @sukvvon
- *: explain why 'vitest-js/valid-expect' is disabled for the 'expectTypeOf(ctx.queryKey)' checks in the 'useQueries' type tests (#12332) (1eed9d9) by @sukvvon
- query-core/query: explain why 'typescript/no-unnecessary-condition' is disabled for the 'state' check in 'setOptions' (#12326) (a155bb8) by @sukvvon
- eslint-plugin-query/detect-react-query-imports: explain why 'typescript/no-unnecessary-condition' is disabled for the 'importKind' check (#12327) (0c5ec06) by @sukvvon
- lit-query/{QueryClientProvider,BaseController}: explain why 'typescript/no-unnecessary-condition' is disabled for the 'client' checks (#12328) (016b83e) by @sukvvon
- angular-query-experimental/createBaseQuery: explain why 'typescript/no-unnecessary-type-assertion' is disabled for the 'refetch' wrapper (#12329) (42ae5ca) by @sukvvon
- deps: upgrade vitest to v5 (#12317) (4a7386a) by @DogPawHat
- vue-query-devtools/package.json: restore the 'test:lib' script removed in the Vite 8 update (#12307) (7a10cda) by @sukvvon
- oxlint.config: add 'netinfo' to the cspell words (#12299) (6580131) by @sukvvon
- preact-query/utils: disable 'react/exhaustive-deps' for the stable '_instance' to keep the upstream 'useSyncExternalStore' (#12289) (2de1d1e) by @sukvvon
- scripts/create-github-release: use the 'node:' protocol for 'fs' and sort the imported members (#12285) (4071cd5) by @sukvvon
- oxlint.config: remove the 'vitest/no-standalone-expect' override left over from the removed 'itIf' helper (#12284) (75e64b5) by @sukvvon
- {react-query,preact-query,query-broadcast-client-experimental}/vite.config: remove the CI-only 'retry' (#12279) (84332de) by @sukvvon
- svelte-query-persist-client/vite.config: enable 'coverage' in CI like the other packages (#12275) (b2246c2) by @sukvvon
- oxlint.config: enable 'no-debugging-utils', 'no-dom-import', 'no-manual-cleanup' and 'no-render-in-lifecycle' from 'eslint-plugin-testing-library' (#12273) (b923947) by @sukvvon
- oxlint.config: add 'eslint-plugin-testing-library' with its DOM rules and query present elements with 'getBy' (#12269) (bb41f83) by @sukvvon
- oxlint.config: add 'eslint-plugin-jest-dom' with its recommended rules and assert DOM presence with 'toBeInTheDocument' (#12268) (670fc28) by @sukvvon
- oxlint.config: enable 'vitest/consistent-each-for' to keep parameterized tests on '.each' (#12267) (496c4ac) by @sukvvon
- oxlint.config: enable 'vitest/prefer-lowercase-title' for test titles (#12266) (883d35e) by @sukvvon
- oxlint.config: enable 'vitest/require-top-level-describe' and move top-level tests and hooks into a 'describe' (#12265) (f5fc7ac) by @sukvvon
- oxlint.config: enable 'vitest-js/padding-around-after-all-blocks' (#12263) (90b5acb) by @sukvvon
- oxlint.config: enable 'vitest-js/padding-around-describe-blocks' and separate describe blocks with a blank line (#12262) (6aaa0cb) by @sukvvon
- oxlint.config: enable 'vitest-js/padding-around-after-each-blocks' and separate 'afterEach' with a blank line (#12261) (62592ae) by @sukvvon
- oxlint.config: enable 'vitest-js/padding-around-before-each-blocks' and separate 'beforeEach' with a blank line (#12260) (28a8540) by @sukvvon
- oxlint.config: enable 'vitest-js/padding-around-before-all-blocks' and separate 'beforeAll' with a blank line (#12259) (4a6264e) by @sukvvon
- oxlint.config: enable 'vitest-js/padding-around-test-blocks' and separate test blocks with a blank line (#12258) (7cafffd) by @sukvvon
- oxlint.config: enable 'vitest-js/no-conditional-in-test' outside type tests (#12256) (914eef7) by @sukvvon
- oxlint.config: enable 'vitest-js/prefer-vi-mocked' (#12255) (d8fbf7e) by @sukvvon
- oxlint.config: enable 'vitest/consistent-test-filename' (#12253) (06d2607) by @sukvvon
- oxlint.config: enable 'vitest/require-mock-type-parameters' and type the mock functions (#12251) (07bdb6b) by @sukvvon
- oxlint.config: enable 'vitest/prefer-strict-equal' and assert with 'toStrictEqual' (#12250) (5c7b9db) by @sukvvon
- oxlint.config: enable 'vitest/require-hook' and move setup code into hooks or tests (#12249) (1616702) by @sukvvon
- oxlint.config: enable 'vitest/prefer-mock-return-shorthand' and use 'mockReturnValue' or 'vi.fn(implementation)' (#12248) (ada9a5e) by @sukvvon
- oxlint.config: enable 'vitest/prefer-to-be' and assert primitive values with 'toBe', 'toBeNull', 'toBeUndefined' and 'toBeDefined' (#12247) (5ba86a6) by @sukvvon
- oxlint.config: enable 'vitest/prefer-to-have-length' and assert lengths with 'toHaveLength' (#12246) (4dc1af9) by @sukvvon
- oxlint.config: enable the vitest style rules that already pass without violations (#12245) (cdb344b) by @sukvvon
- oxlint.config: enable 'vitest/prefer-import-in-mock' and type the module mocks against the real modules (#12243) (c1dc50c) by @sukvvon
- oxlint.config: enable 'vitest/prefer-expect-resolves' and assert resolved values with 'resolves' (#12244) (03b3f90) by @sukvvon
- oxlint.config: enable 'vitest/prefer-mock-promise-shorthand' and use 'mockResolvedValue' and 'mockRejectedValue' (#12242) (5393cdc) by @sukvvon
- oxlint.config: enable 'vitest/prefer-spy-on' and spy on 'query.fetch' instead of overwriting it (#12241) (3afe752) by @sukvvon
- oxlint.config: enable 'vitest/prefer-called-times' and replace 'toHaveBeenCalledOnce' with 'toHaveBeenCalledTimes(1)' (#12240) (9648f0e) by @sukvvon
- oxlint.config: enable 'vitest/no-alias-methods' and replace 'toBeCalledWith' with 'toHaveBeenCalledWith' (#12239) (52ebbb3) by @sukvvon
- oxlint.config: enable 'vitest/prefer-called-with' and assert the call arguments with 'toHaveBeenCalledWith' (#12237) (22d9966) by @sukvvon
- oxlint.config: enable 'vitest/prefer-expect-type-of' and assert the 'staleTime' type with 'toBeTypeOf' (#12236) (25ed6ae) by @sukvvon
- oxlint.config: enable 'vitest/prefer-to-contain' and assert array membership with 'toContain' (#12235) (c51b851) by @sukvvon
- oxlint.config: enable 'vitest/prefer-equality-matcher' and compare the value directly with 'toBe' (#12234) (af28a1b) by @sukvvon
- oxlint.config: enable 'vitest/require-to-throw-message' and assert the expected error messages in 'toThrow' (#12233) (7e7a1c9) by @sukvvon
- oxlint.config: enable vitest rules that already pass without violations (#12232) (1667b24) by @sukvvon
- examples/vue/persister/package.json: remove the unused '@tanstack/query-core' and '@tanstack/query-sync-storage-persister' dependencies (#12146) (3c540d3) by @sukvvon
- examples/vue/{2.6-basic,2.7-basic}: add a flat config and run 'test:eslint' (#12136) (f7c89b6) by @sukvvon
Packages
- @tanstack/angular-query-experimental@5.105.0
- @tanstack/eslint-plugin-query@5.105.0
- @tanstack/lit-query@0.2.31
- @tanstack/preact-query@5.105.0
- @tanstack/preact-query-devtools@5.105.0
- @tanstack/preact-query-persist-client@5.105.0
- @tanstack/query-async-storage-persister@5.105.0
- @tanstack/query-broadcast-client-experimental@5.105.0
- @tanstack/query-core@5.105.0
- @tanstack/query-devtools@5.105.0
- @tanstack/query-persist-client-core@5.105.0
- @tanstack/query-sync-storage-persister@5.105.0
- @tanstack/react-query@5.105.0
- @tanstack/react-query-devtools@5.105.0
- @tanstack/react-query-next-experimental@5.105.0
- @tanstack/react-query-persist-client@5.105.0
- @tanstack/solid-query@5.105.0
- @tanstack/solid-query-devtools@5.105.0
- @tanstack/solid-query-persist-client@5.105.0
- @tanstack/svelte-query@6.3.6
- @tanstack/svelte-query-devtools@6.3.6
- @tanstack/svelte-query-persist-client@6.3.6
- @tanstack/vue-query@5.105.0
- @tanstack/vue-query-devtools@6.3.6