Eden TanStack Query
Comparisons

Comparisons

How eden-tanstack-query compares to @ap0nia/eden-react-query and tRPC

Comparisons

Quick Comparison

Featureeden-tanstack-query@ap0nia/eden-react-querytRPC v11
BackendElysiaElysiaAny (adapters)
API StyleOptions-basedWrapper hooks + cache utilitiesOptions-based (@trpc/tanstack-react-query)
TransportPlain REST (HTTP methods, URLs)REST + optional batchingRPC protocol
Query KeysExplicit utilitiestRPC-style utilsExplicit utilities
TQ IntegrationNative hooksWrapper hooksNative hooks
Learning CurveStandard TanStack QuerytRPC-style APIStandard TanStack Query

vs @ap0nia/eden-react-query

API Comparison

Basic Query

eden-tanstack-query
const eden = useEden()
const { data } = useQuery(eden.users.get.queryOptions())
@ap0nia/eden-react-query
const { data } = eden.users.get.useQuery()

Mutations

eden-tanstack-query
const createUser = useMutation({
  ...eden.users.post.mutationOptions(),
  onSuccess: () => {
    queryClient.invalidateQueries({ queryKey: eden.users.get.queryKey() })
  }
})
@ap0nia/eden-react-query
const utils = eden.useUtils()
const createUser = eden.users.post.useMutation({
  onSuccess: () => utils.users.get.invalidate()
})

Key Differences

Options-based vs wrapper hooks — eden-tanstack-query generates options objects that work with any TanStack Query hook (useQuery, useSuspenseQuery, prefetchQuery, fetchQuery). eden-react-query provides tRPC-style wrapper hooks on the route proxy and cache utilities through useUtils().

Explicit query keys — eden-tanstack-query exposes .queryKey(), .queryFilter(), and .infiniteQueryFilter() for full control over cache invalidation. eden-react-query manages keys through tRPC-style utils.

Standard patterns — If you know TanStack Query, you already know eden-tanstack-query. No custom API to learn.

When to Choose

Choose eden-tanstack-queryChoose @ap0nia/eden-react-query
Standard TanStack Query patternsPrefer tRPC-style wrapper hooks
Explicit cache control neededUtils-based invalidation feels natural
Complex invalidation patternsComing from tRPC and want that API
Already familiar with TanStack QueryBatching support wanted

Migration from @ap0nia/eden-react-query

1. Update imports

// Before
import { createEdenTreatyReactQuery } from '@ap0nia/eden-react-query'

const eden = createEdenTreatyReactQuery<App>()

// After
import { createEdenTanStackQuery } from 'eden-tanstack-react-query'
import { treaty } from '@elysiajs/eden'

2. Setup provider

const { EdenProvider, useEden } = createEdenTanStackQuery<App>()
const edenClient = treaty<App>('http://localhost:3000')

<QueryClientProvider client={queryClient}>
  <EdenProvider client={edenClient} queryClient={queryClient}>
    <App />
  </EdenProvider>
</QueryClientProvider>

3. Update queries

// Before: eden.users.get.useQuery()
// After:
const eden = useEden()
const { data } = useQuery(eden.users.get.queryOptions())

4. Update mutations

// Before: eden.users.post.useMutation()
// After:
const mutation = useMutation(eden.users.post.mutationOptions())

5. Update cache operations

// Before:
const utils = eden.useUtils()
utils.users.get.invalidate()

// After:
queryClient.invalidateQueries(eden.users.get.queryFilter())

vs tRPC

Code Comparison

Server

Elysia
const app = new Elysia()
  .get('/users', () => db.users.findMany())
  .get('/users/:id', ({ params }) => db.users.findUnique({
    where: { id: params.id }
  }))
  .post('/users', ({ body }) => db.users.create({ data: body }), {
    body: t.Object({ name: t.String(), email: t.String({ format: 'email' }) })
  })

export type App = typeof app
tRPC
const appRouter = t.router({
  users: t.router({
    list: t.procedure.query(() => db.users.findMany()),
    get: t.procedure
      .input(z.object({ id: z.string() }))
      .query(({ input }) => db.users.findUnique({ where: { id: input.id } })),
    create: t.procedure
      .input(z.object({ name: z.string(), email: z.string().email() }))
      .mutation(({ input }) => db.users.create({ data: input }))
  })
})

export type AppRouter = typeof appRouter

Client

eden-tanstack-query
const eden = useEden()
const { data } = useQuery(eden.users.get.queryOptions())

const createUser = useMutation({
  ...eden.users.post.mutationOptions(),
  onSuccess: () => queryClient.invalidateQueries(eden.users.get.queryFilter())
})
tRPC (@trpc/tanstack-react-query)
const trpc = useTRPC()
const queryClient = useQueryClient()

const { data } = useQuery(trpc.users.list.queryOptions())

const createUser = useMutation(trpc.users.create.mutationOptions({
  onSuccess: () => queryClient.invalidateQueries(trpc.users.list.queryFilter())
}))

Since tRPC v11, @trpc/tanstack-react-query offers the same options-based surface as this library (queryOptions, queryKey, queryFilter, infiniteQueryOptions, mutationOptions, mutationKey). The differences that remain are about the backend and the transport, not the client API style.

Key Differences

Aspecteden-tanstack-querytRPC v11
BackendElysia (Bun)Any (Node.js, Bun, etc.)
API styleREST (HTTP methods, URL paths)RPC (procedures in routers)
Client surfaceOptions factories + explicit keysOptions factories + explicit keys
TransportPlain HTTP requests, no codectRPC link protocol, optional batching
EcosystemElysia pluginsLarge tRPC ecosystem
ToolingStandard REST tools (curl, Postman)Requires tRPC-aware clients

When to Choose

Choose eden-tanstack-queryChoose tRPC
Using Elysia + BunNeed backend framework flexibility
Prefer REST conventionsNeed request batching
Types flow from real HTTP routesExisting tRPC codebase
Standard HTTP tooling neededNeed the larger ecosystem

On this page