Skip to content

TanStack Start Adapter

TanStack Start is a full-stack React framework built on Vite and the Fetch API. For additional context, see the HTTP Adapter guide.

Server

You set up an oRPC server inside TanStack Start using its Server Routes.

ts
import { RPCHandler } from '@orpc/server/fetch'
import { createServerFileRoute } from '@tanstack/react-start/server'

const handler = new RPCHandler(router)

async function handle({ request }: { request: Request }) {
  const { response } = await handler.handle(request, {
    prefix: '/api/rpc',
    context: {}, // Provide initial context if needed
  })

  return response ?? new Response('Not Found', { status: 404 })
}

export const ServerRoute = createServerFileRoute('/api/rpc/$').methods({
  HEAD: handle,
  GET: handle,
  POST: handle,
  PUT: handle,
  PATCH: handle,
  DELETE: handle,
})

INFO

The handler can be any supported oRPC handler, including RPCHandler, OpenAPIHandler, or a custom handler.

Client

Use createIsomorphicFn to configure the RPC link with environment-specific settings for both browser and SSR environments:

ts
import { RPCLink } from '@orpc/client/fetch'
import { createIsomorphicFn } from '@tanstack/react-start'
import { getHeaders } from '@tanstack/react-start/server'

const getClientLink = createIsomorphicFn()
  .client(() => new RPCLink({
    url: `${window.location.origin}/api/rpc`,
  }))
  .server(() => new RPCLink({
    url: 'http://localhost:3000/api/rpc',
    headers: () => getHeaders(),
  }))

INFO

This only shows how to configure the link. For full client examples, see Client-Side Clients.

Optimize SSR

To reduce HTTP requests and improve latency during SSR, you can utilize a Server-Side Client during SSR. Below is a quick setup, see Optimize SSR for more details.

ts
import { createRouterClient } from '@orpc/server'
import type { RouterClient } from '@orpc/server'
import { createORPCClient } from '@orpc/client'
import { RPCLink } from '@orpc/client/fetch'
import { getHeaders } from '@tanstack/react-start/server'
import { createIsomorphicFn } from '@tanstack/react-start'

const getORPCClient = createIsomorphicFn()
  .server(() => createRouterClient(router, {
    /**
     * Provide initial context if needed.
     *
     * Because this client instance is shared across all requests,
     * only include context that's safe to reuse globally.
     * For per-request context, use middleware context or pass a function as the initial context.
     */
    context: async () => ({
      headers: getHeaders(), // provide headers if initial context required
    }),
  }))
  .client((): RouterClient<typeof router> => {
    const link = new RPCLink({
      url: `${window.location.origin}/api/rpc`,
    })

    return createORPCClient(link)
  })

export const client: RouterClient<typeof router> = getORPCClient()

Released under the MIT License.