Add createQuery and createMutation, replacing solid-query - #284
Merged
Conversation
added 2 commits
September 2, 2026 15:48
Every application here reads its data through `@tanstack/solid-query` -- 308 files and roughly a thousand call sites across ten sites -- and nothing in this library offers an alternative, so there has been nowhere to migrate to. This is that alternative. It is not a like-for-like port. One behaviour is deliberately different, and it is the reason for writing this rather than wrapping the old one: A query that has not run is not pending, and reading it never suspends. TanStack parks a query that has never fetched -- including one held back by `enabled: false` -- at `status: "pending"`. Reading a pending query under Solid 2 throws `NotReadyError` to suspend, so a query that is disabled suspends for the lifetime of the page. `NotReadyError` extends `Error` with no message and does not override `name`, so a boundary catching one has nothing to print. That combination took every authenticated route of an application down behind a blank error page, and the cause was a chat button whose queries had never been allowed to run. Here `data()` is undefined until there is data, `isLoading()` is true only while a fetch is in flight, and neither ever throws. A caller that wants to suspend can; a caller that forgets cannot take the page with it. `invalidateQueries` is a plain function rather than something read from context, because invalidation is usually wanted from a mutation handler or a store, neither of which is a component.
Inferred, it is the union of `render`'s `JSX.Element` and `formatCell`'s `string`, and naming that union in a declaration needs `RenderedElement` -- internal to `solid-js`, with no importable path from here. That is TS2883. Whether the compiler reaches for that name depends on how `solid-js` is hoisted, so the file type-checks against a local `node_modules` and fails against CI's clean install. The annotation removes the dependency on that shape rather than papering over the difference.
pathscale
force-pushed
the
feat/data-primitives-replacing-tanstack
branch
from
September 2, 2026 08:49
0da1d90 to
670b040
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First step of removing
@tanstack/solid-queryfrom every app. This adds the thing there is currently nowhere to migrate to.Why
The audit across
~/code: 308 files, ~1000 call sites, ten sites, all@tanstack/solid-query@6.0.0-rc.1. There is zero@tanstack/solid-tableanywhere — the grid side is already on this library. It is only the data layer that was never ported.Nothing in
UI/src/hooksoffered a replacement (date,form,layout,table), and Solid 2 core does not shipcreateResourceorcreateAsync— its async surface iscreateProjection,isPending,latest,onSettled,action. So "remove TanStack" first required writing what replaces it.The one deliberate behaviour difference
TanStack parks a query that has never fetched — including one held back by
enabled: false— atstatus: "pending". Reading a pending query under Solid 2 throwsNotReadyErrorto suspend, so a permanently-disabled query suspends for the lifetime of the page.NotReadyError extends Errorcallssuper()with no message and does not overridename, so a boundary that catches one has nothing to print.That combination took down every authenticated route of honey.id behind a red "An error occurred" over a blank line. The actual fault was a chat button whose support.cafe queries had never been allowed to run.
Here
data()isundefineduntil there is data,isLoading()is true only while a fetch is in flight, and neither ever throws. A caller that wants to suspend can do so explicitly; a caller that forgets cannot take the page with it.API
The options-thunk shape matches TanStack's Solid signature deliberately, so the migration of ~1000 call sites is mechanical rather than a rewrite.
invalidateQueries(prefix)replacesuseQueryClient().invalidateQueries({ queryKey })and matches by key prefix the same way. It is a plain function rather than something read from context, because invalidation is usually wanted from a mutation handler or a store, neither of which is a component.Verification
bun test --conditions=browser src/hooks/data— 7 pass. The first test is the regression that started this: a disabled query is not loading, never fetches, and never throws.bunx tsc --noEmitclean.bun run linton the changed files is clean. The repo-widebun run lintexits 1 onmastertoo — pre-existing, and I checked the baseline rather than assuming. Its fixer also rewroteCalendar.layout.tsxandInputOTP.layout.tsx, which my change never touched; those were reverted and are not in this diff.Notably not covered by tests: concurrent-key races beyond the generation guard, and behaviour under
Loadingboundaries. Both are worth exercising once a real app is migrated onto this.What follows
HoneyAuthpanel in this library, so login stops being hand-rolled per app