Skip to content
qt

@tanstack-tools/query-tags

TypeScriptTanStack QueryTanStack StartSPA + BackendMIT License

Next.js has revalidateTag.
TanStack didn't. Until now.

Tag-based cache invalidation for TanStack Query — works with TanStack Start, or a SPA + separate backend (Express, Hono, Fastify, Elysia, Koa). One invalidateTag() on the server. Every subscribed query updates. Every tab. Automatically.

$pnpm add @tanstack-tools/query-tags

Manual cache invalidation doesn't scale

Every mutation must know about every query it affects. Add a query, update every mutation. Forget one? Stale data. Tags flip this: queries declare what data they need, and the server invalidates by meaning — not by key.

See the full comparison →

Try it now

30-second demo

Add a todo and watch both query panels update automatically. No invalidateQueries anywhere in the mutation code.

Live Demo— try it now

No todos yet

Todo Count

0

todos.list
Summary

0 total

todos.summary

Add a todo and watch both panels flash green simultaneously — zero manual invalidation

How it works

Three steps to automatic invalidation

1

Define tags

defineTags({
  todos: {
    list: () => ["todos"],
    byId: (id) => ["todo", id],
  }
})

Create a typed tag tree. Full autocomplete, compile-time safety.

2

Tag your queries

useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodos,
  meta: { tags: [appTags.todos.list()] }
})

One line in meta. Or use withTags() for zero-boilerplate.

3

Invalidate from server

await tagInvalidation.invalidateTags({
  tags: [appTags.todos()]
})
// Every tagged query refreshes.

Server decides. Clients react. SSE delivers. Done.

Comparison

query-tags vs alternatives

How does it stack up against rolling your own or using Next.js revalidateTag?

FeatureManualNext.js
revalidateTag
query-tags
Type-safe tag references
Multi-tab sync
Hierarchical invalidation
Per-tenant scoping
Route loader refresh
Works with TanStack Query
No framework lock-in
Debug tooling
~

20

entry points

28

live demos

0

manual refetches

100%

TypeScript

Built on the TanStack ecosystem

Required:TanStack QueryTanStack RouterReact 19
Compatible:TanStack StartExpressHonoFastifyElysiaKoa

Tag Groups

Invalidate a parent tag and all children refresh automatically. No more listing every query key.

Multi-Tab Sync

SSE pushes invalidation to all connected clients. Open two tabs — they just sync.

Scope Isolation

Per-user, per-tenant, or global scopes. Multi-tenant apps get isolation for free.

Debug Tools

See every SSE event, every tag match, pause/resume the system. Full observability.

Framework Adapters

One-line wiring for Express, Hono, Fastify, Elysia, and Koa — same SSE engine, same invalidation API.

Recommended path

New here? Follow this order

A guided sequence from first principles to production-ready patterns.

  1. 1Why query-tags
  2. 2How It Works
  3. 3Quickstart
  4. 4Integration Guide
  5. 5Standalone (SPA + Backend)
  6. 6Tag Design
  7. 7Migration Guide
  8. 8Gotchas
  9. 9Cookbook
  10. 10Examples
  11. 11Playground

Explore

See it in real-world scenarios

Get started

Ready to try it?

Add the plugin, define your tags, and never write a manual invalidateQueries again.

$pnpm add @tanstack-tools/query-tags