Appearance
Why TanStack DB?
TT Time Tracker uses @tanstack/vue-db alongside the more familiar @tanstack/vue-query. This article explains why.
The problem with plain TanStack Query for this app
TanStack Query is excellent at fetching and caching server data. It works well when you display a list, a user takes an action, and then you refetch the list. The request/response cycle is the source of truth.
TT Time Tracker has a different pattern: the admin dashboard shows a large dataset that needs to be filtered, searched, and updated interactively without a full round-trip per interaction. Time entries are loaded once, then filtered by user, date range, project, and approval status — all combinations the user can toggle in real time.
With plain TanStack Query, each filter combination would either:
- Require a new API request (slow, expensive)
- Require manual client-side filtering over a cached result (leads to inconsistent cache keys, stale data, and complex synchronisation logic)
What TanStack DB adds
@tanstack/vue-db is a lightweight in-memory relational store with reactivity built in. Collections are loaded from the API and held in memory. useLiveQuery subscribes to a collection with a filter function that re-runs automatically whenever the underlying data changes.
typescript
// This re-evaluates instantly when entries change or filters change
const pendingEntries = useLiveQuery(entriesCollection, (entry) =>
entry.tenantId === tenantId.value &&
entry.approved === false &&
entry.archived === false
)No extra API requests. No cache key juggling. The filter is just a function.
The trade-off
TanStack DB is a newer, less battle-tested library. It adds a dependency and introduces a slightly different mental model (collections vs queries). The API is smaller and sometimes changes between minor versions.
The bet is that for this specific use case — reactive in-memory filtering over moderate-sized datasets — the developer experience and performance benefit outweighs the cost of the dependency.
If TanStack DB causes problems in the future, the collections can be replaced with Pinia stores and plain computed properties without changing the component layer significantly.