Why a stub?
The maintained runtime is Next.js Web and its satellite apps. Rust (apps/backend) and TanStack Start (apps/tanstack-web) are paused and not in
use. Docker setup is inactive and the Docker cron runner is retired. Retained
migration designs describe a possible future, not live traffic or a current
setup requirement. See the active runtime map.
Rather than build out a tRPC API surface that would be thrown away, the team
keeps a minimal tRPC scaffold wired end-to-end so the type system and client
plumbing stay valid and ready, while all real reads and writes go through the
internal API client and REST routes. New product features should not add
tRPC routers — use the patterns in
Data Fetching and
API Routes.
A repository guard (
scripts/check-tanstack-api-access.js, run as part of
bun validate) forbids calls to /trpc from apps/tanstack-web/src. The
TanStack app talks to the Rust backend and REST API, never to this stub.What actually exists today
apps/web/package.json: @trpc/server, @trpc/client,
and @trpc/react-query are all on ^11.x, paired with
@tanstack/react-query ^5.x and superjson ^2.x. (Check the manifest for
exact pinned versions; do not hard-code them in code.)
Initialization (init.ts)
init.ts creates the tRPC instance with the superjson transformer and exports
helper factories. Note the real export names — there is no router,
publicProcedure, or protectedProcedure.
The root router (routers/_app.ts)
The entire API surface is one health-check query that keeps the tRPC type system
compiling:
appRouter.healthCheck.
The route handler (app/api/trpc/[trpc]/route.ts)
A standard tRPC fetch adapter exposes the router over HTTP for both GET and
POST:
Query client (query.ts)
makeQueryClient builds a TanStack Query v5 QueryClient with superjson
de/serialization and rate-limit-aware retries. This is shared by both the client
provider and the RSC caller.
On TanStack Query v5, the cache-retention option is
gcTime, not the v4
cacheTime. The factory above relies on the v5 default gcTime; if you set it
explicitly anywhere, use gcTime.Client provider (client.tsx)
client.tsx creates the typed React client with createTRPCReact<AppRouter>()
and wires a TRPCProvider over @tanstack/react-query. The HTTP batch link
points at /api/trpc and uses the superjson transformer.
Server caller and hydration (server.ts)
server.ts builds an RSC-side caller from the root router plus the same query
client, and exposes trpc and HydrateClient via tRPC’s
createHydrationHelpers. It is marked server-only.
How to actually fetch product data
Because tRPC is a stub, real data access uses the platform’s standard stack:- Server Components read data directly (via Supabase server clients and
@tuturuuu/internal-apihelpers) and pass it down as props. - Client components use TanStack Query v5 hooks wrapping
@tuturuuu/internal-apihelpers / REST/api/v1routes. Never fetch inuseEffect, and never call raw app APIs from the client directly. - Realtime updates are wired into the TanStack Query cache, not into
useEffect.
@tuturuuu/supabase/next/server,
remember:
Extending the stub (rarely needed)
If you genuinely need to add a procedure to the stub (for example, another lightweight diagnostic), follow the real helper names:@tuturuuu/internal-api + REST routes instead of
growing this scaffold during the migration.
Related Documentation
- Data Fetching — the real client/server fetching stack (Server Components + internal-api + TanStack Query)
- API Routes — REST
/api/v1patterns and@tuturuuu/internal-api - TanStack + Rust migration — why this layer is a stub
- Authentication
- Authorization