Eden TanStack Query
API Reference

useEden

Proxy hook with all route methods for queries, mutations, and cache operations

useEden

The useEden hook returns an options proxy that mirrors your Elysia API structure. Each route is decorated with TanStack Query methods.

function useEden(): EdenOptionsProxy<TApp>

Returns an EdenOptionsProxy<TApp> — a proxy object that mirrors your API routes, handles path parameters via function calls, and decorates each endpoint with query/mutation methods.

Route Methods

Query Routes (GET, HEAD, OPTIONS)

MethodDescription
queryOptionsCreates options for useQuery / useSuspenseQuery
queryKeyGenerates a query key for cache operations
queryFilterCreates a filter for invalidateQueries, cancelQueries, etc.
infiniteQueryOptionsCreates options for useInfiniteQuery
infiniteQueryKeyGenerates an infinite query key
infiniteQueryFilterCreates a filter for infinite queries

Mutation Routes (POST, PUT, PATCH, DELETE)

MethodDescription
mutationOptionsCreates options for useMutation
mutationKeyGenerates a mutation key

queryOptions

Creates type-safe options for useQuery, useSuspenseQuery, prefetchQuery, and other TanStack Query functions.

eden.route.get.queryOptions(input?, opts?): QueryOptions

Parameters

ParameterTypeDescription
inputTInput | SkipTokenQuery parameters or skipToken to disable
optsEdenQueryOptionsInTanStack Query options (excluding reserved)

Returns

PropertyTypeDescription
queryKeyDataTag<EdenQueryKey>Unique key based on path and input
queryFnQueryFunctionFetch function via Eden client
eden{ path: string }Route metadata

Reserved Options

Automatically set and cannot be overridden: queryKey, queryFn, queryHash, queryHashFn.

Eden-specific Options

OptionTypeDescription
eden.abortOnUnmountbooleanAbort request when component unmounts

Example

const eden = useEden()

// Basic
const { data } = useQuery(eden.users.get.queryOptions())

// With query params and TQ options
const { data } = useQuery(
  eden.users.get.queryOptions(
    { role: 'admin' },
    { staleTime: 5 * 60 * 1000 }
  )
)

// Path params
const { data } = useQuery(
  eden.users({ id: '123' }).get.queryOptions()
)

// Conditional with skipToken
const { data } = useQuery(
  eden.users({ id: userId ?? '' }).get.queryOptions(
    userId ? undefined : skipToken
  )
)

mutationOptions

Creates type-safe options for useMutation.

eden.route.post.mutationOptions(opts?): MutationOptions

Parameters

ParameterTypeDescription
optsEdenMutationOptionsInTanStack Query mutation options (excluding reserved)

Returns

PropertyTypeDescription
mutationKeyEdenMutationKeyUnique key based on route path
mutationFnMutationFunctionMutation function via Eden client
eden{ path: string }Route metadata

Reserved Options

Automatically set: mutationKey, mutationFn.

Example

const eden = useEden()
const queryClient = useQueryClient()

const createUser = useMutation({
  ...eden.users.post.mutationOptions(),
  onSuccess: () => {
    queryClient.invalidateQueries({ queryKey: eden.users.get.queryKey() })
  }
})

createUser.mutate({ name: 'Alice', email: 'alice@example.com' })

infiniteQueryOptions

Creates type-safe options for useInfiniteQuery with cursor-based pagination.

eden.route.get.infiniteQueryOptions(input, opts): InfiniteQueryOptions

Parameters

ParameterTypeDescription
inputTInput | SkipTokenQuery params (excluding cursor) or skipToken
opts.getNextPageParam(lastPage) => TCursor | undefinedRequired. Returns next page cursor
opts.initialCursorTCursorInitial cursor value. Defaults to null
opts.getPreviousPageParam(firstPage) => TCursor | undefinedFor bi-directional pagination
opts.maxPagesnumberMax pages to keep in memory

Example

const eden = useEden()

const { data, fetchNextPage, hasNextPage } = useInfiniteQuery(
  eden.posts.get.infiniteQueryOptions(
    { limit: 10 },
    {
      getNextPageParam: (lastPage) => lastPage.nextCursor ?? undefined,
      initialCursor: null,
    }
  )
)

queryKey

Generates a typed query key for cache operations.

eden.route.get.queryKey(input?): DataTag<EdenQueryKey>

Key structure:

eden.users.get.queryKey()
// => [['users', 'get'], { type: 'query' }]

eden.users.get.queryKey({ role: 'admin' })
// => [['users', 'get'], { input: { role: 'admin' }, type: 'query' }]

eden.users({ id: '1' }).get.queryKey()
// => [['users', 'get'], { input: { id: '1' }, type: 'query' }]

mutationKey

Generates a mutation key from route path.

eden.route.post.mutationKey(): EdenMutationKey
eden.users.post.mutationKey()
// => [['users', 'post']]

infiniteQueryKey

Generates an infinite query key (separate from regular query cache).

eden.route.get.infiniteQueryKey(input?): DataTag<EdenQueryKey>
eden.posts.get.infiniteQueryKey()
// => [['posts', 'get'], { type: 'infinite' }]

eden.posts.get.infiniteQueryKey({ category: 'tech' })
// => [['posts', 'get'], { input: { category: 'tech' }, type: 'infinite' }]

queryFilter

Creates a query filter for bulk cache operations like invalidateQueries, cancelQueries, removeQueries.

eden.route.get.queryFilter(input?, filters?): QueryFilters
ParameterTypeDescription
inputTInputOptional input to narrow the filter
filtersQueryFilterOptionsTanStack Query filter options (exact, type, stale, fetchStatus, predicate)
// Invalidate all user queries
queryClient.invalidateQueries(eden.users.get.queryFilter())

// Invalidate with specific input
queryClient.invalidateQueries(
  eden.users.get.queryFilter({ role: 'admin' }, { exact: false })
)

infiniteQueryFilter

Same as queryFilter but scoped to infinite queries.

eden.route.get.infiniteQueryFilter(input?, filters?): QueryFilters
queryClient.invalidateQueries(eden.posts.get.infiniteQueryFilter())

Low-level APIs

For use outside React context (loaders, server components, utilities):

import {
  edenQueryOptions,
  edenMutationOptions,
  edenInfiniteQueryOptions,
} from 'eden-tanstack-react-query'

// edenQueryOptions
const opts = edenQueryOptions({
  path: ['users', 'get'],
  input: { role: 'admin' },
  fetch: async (input, signal) => { /* ... */ },
  opts: { staleTime: 5000 }
})

// edenMutationOptions
const opts = edenMutationOptions({
  path: ['users', 'post'],
  mutate: async (input) => { /* ... */ },
})

// edenInfiniteQueryOptions
const opts = edenInfiniteQueryOptions({
  path: ['posts', 'get'],
  input: { limit: 10 },
  initialPageParam: null as string | null,
  fetch: async (inputWithCursor, signal) => { /* ... */ },
  opts: { getNextPageParam: (lastPage) => lastPage.nextCursor ?? undefined }
})

Types

DecorateQueryProcedure

Methods on GET/HEAD/OPTIONS routes:

MethodTypeDescription
queryOptions(input?, opts?) => EdenQueryOptionsOptions for useQuery
queryKey(input?) => DataTag<EdenQueryKey>Query key for cache ops
queryFilter(input?, filters?) => QueryFiltersFilter for invalidation

DecorateInfiniteQueryProcedure

Methods on query routes with cursor input:

MethodTypeDescription
infiniteQueryOptions(input, opts) => EdenInfiniteQueryOptionsOptions for useInfiniteQuery
infiniteQueryKey(input?) => DataTag<EdenQueryKey>Infinite query key
infiniteQueryFilter(input?, filters?) => QueryFiltersFilter for infinite queries

DecorateMutationProcedure

Methods on POST/PUT/PATCH/DELETE routes:

MethodTypeDescription
mutationOptions(opts?) => EdenMutationOptionsOptions for useMutation
mutationKey() => EdenMutationKeyMutation key

On this page