Query() caching with stale-while-revalidate (TanStack Query style): avoid loaders on every return visit
Maintainers usually reply within 1 day
@iambharathpadhu is already working on this.
Since Jul 9, 2026.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- typescript
- Domain
- backend-api-design
Research direction
Start by reading the runtime and toolProvider layer mentioned in the issue, then compare the runtime-level cache and middleware approaches with the maintainers before choosing a scope. The request includes caching, invalidation, persistence, and optional retry and optimistic updates, so agree on which behavior to implement first. Done should mean the agreed behavior works for repeated queries and is covered by tests.
Written by the indexing model from the issue text.
Description
Hi folks 👋 I've been using OpenUI for a while now and it's genuinely great, but there's one gap that hurts the UX of everything we build with it: there's no caching between Query() and our tools, so users see loading placeholders every single time they navigate away and come back to a page, even when we fetched that exact data seconds ago.
What I'd love to see is TanStack Query style caching with stale-while-revalidate as the default behavior: when a user returns to a page, render the cached result instantly, then re-fetch in the background and update in place. No spinner, no default-value placeholder flash, and the data still ends up fresh.
The existing pieces are a solid foundation. Reactive $variable changes re-fetch dependent queries, the optional refresh-interval argument covers polling, and @Run gives manual control. What's missing is the cache layer itself:
- Stale-while-revalidate rendering: serve the last known result for a given tool + args immediately, revalidate in the background. This is the big one for us.
- Stale-time / cache-time control: let us say how long a result is considered fresh, so repeat visits within that window don't hit the backend at all.
- Request deduplication: multiple components querying the same tool with the same args should share one in-flight request.
- Declarative invalidation: today the post-mutation pattern is
@Run(createResult), @Run(tickets), which means the LLM has to know every query a mutation affects. Tag-based invalidation (mutation invalidates"tickets", every query tagged"tickets"refetches) would be more robust to generation errors. - Cache persistence: opt-in persistence to
localStorage/IndexedDB, so even a full reload or a returning session starts from cached data instead of spinners. - (Stretch) Retry with backoff and optimistic updates on mutations.
Since OpenUI already separates generation from execution, this fits naturally in the runtime/toolProvider layer: zero new tokens from the model, and it could even ship as a toolProvider middleware without touching OpenUI Lang itself.
With this, Queries and Mutations in OpenUI would honestly be a killer feature. I'm very open to contributing the implementation if the maintainers can weigh in on the preferred design (runtime-level cache vs. toolProvider middleware). Thank you!
- Dominant language
- TypeScript
- Stars
- 10k
- Forks
- 698
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 148
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from thesysdev/openui
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
thesysdev/openui#1445 · 2 comments ·
Maintainers usually reply within 1 day
-
Add dataInvention flag to PromptOptions to disable the 'generate realistic/plausible data' ruleOpen
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
thesysdev/openui#959 · 2 comments ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 18/100
Maintainers usually reply within 1 day
All issues in thesysdev/openui
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
Maintainers usually reply within 2 days
-
reproduced
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
anomalyco/opencode#62052 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
strapi/design-system#2084 ·
Maintainers usually reply within 3 days
-
check:passed streams:remove
Difficulty 1/5 Under an hour Newbie friendliness 67/100
Maintainers usually reply within 1 day
-
OAuth documentation for GET /api/v2/users/me/ appears inconsistent with required global read scopeOpen
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day