Eden TanStack Query
Comparisons

Comparisons

How eden-tanstack-query compares to @elysiajs/eden-query and tRPC

Comparisons

Quick Comparison

Featureeden-tanstack-query@elysiajs/eden-querytRPC
BackendElysiaElysiaAny (adapters)
API StyleOptions-basedWrapper hooksWrapper hooks
Query KeysExplicit utilitiesImplicitImplicit (via utils)
TQ IntegrationNative hooksCustom wrappersCustom wrappers
Bundle Size~2.5 KBLargerLarger
Learning CurveStandard TanStack QueryCustom APICustom API

vs @elysiajs/eden-query

API Comparison

Basic Query

eden-tanstack-query
const eden = useEden()
const { data } = useQuery(eden.users.get.queryOptions())
@elysiajs/eden-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() })
  }
})
@elysiajs/eden-query
const createUser = eden.users.post.useMutation({
  onSuccess: () => {
    // Query invalidation is less explicit
  }
})

Key Differences

Options-based vs wrapper hooks — eden-tanstack-query generates options objects that work with any TanStack Query hook (useQuery, useSuspenseQuery, prefetchQuery, fetchQuery), while eden-query provides custom wrapper hooks with a different API surface.

Explicit query keys — eden-tanstack-query exposes .queryKey(), .queryFilter(), and .infiniteQueryFilter() for full control over cache invalidation. eden-query handles keys implicitly, making complex cache operations harder.

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 @elysiajs/eden-query
Standard TanStack Query patterns"Batteries included" approach
Explicit cache control neededDon't need fine-grained cache control
Complex invalidation patternsOfficial Elysia ecosystem support
Already familiar with TanStack QuerySimpler API surface preferred

Migration from eden-query

1. Update imports

// Before
import { edenTreaty } from '@elysiajs/eden-query'

// 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: queryClient.invalidateQueries(['eden', 'users'])
// 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
const { data } = trpc.users.list.useQuery()

const utils = trpc.useUtils()
const createUser = trpc.users.create.useMutation({
  onSuccess: () => utils.users.list.invalidate()
})

Key Differences

Aspecteden-tanstack-querytRPC
BackendElysia (Bun)Any (Node.js, Bun, etc.)
API styleREST (HTTP methods, URL paths)RPC (procedures in routers)
Cache managementExplicit keys + filtersUtils pattern
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
Want standard TQ patternsExisting tRPC codebase
Standard HTTP tooling neededNeed the larger ecosystem

On this page