Stop manually setting up tRPC in Next.js — use this CLI instead

Published: (March 7, 2026 at 01:28 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

Introduction

Every time I start a new Next.js project with tRPC I have to: open the docs, copy files, install packages, wrap layout.tsx, fix the QueryClient error, and repeat the process for the next project. To eliminate this repetitive setup I created a CLI:

npx create-trpc-setup

What the CLI Does

Running the command inside any existing Next.js project automatically:

  • Installs the required packages (@trpc/server, @trpc/client, @trpc/tanstack-react-query, @tanstack/react-query, zod, etc.).
  • Detects your package manager (npm, pnpm, yarn, bun).
  • Reads tsconfig.json to respect path aliases (@/*, ~/, or custom aliases).
  • Detects authentication providers (Clerk or NextAuth) and configures the context accordingly.
  • Adjusts to your folder structure (src/ or root layout).

It then generates the following files:

trpc/
├── init.ts         ← context, baseProcedure, protectedProcedure, Zod error formatter
├── query-client.ts ← SSR‑safe QueryClient
├── client.tsx      ← TRPCReactProvider + useTRPC hook
├── server.tsx      ← prefetch, HydrateClient, caller
└── routers/
    └── _app.ts     ← health + greet procedures with Zod

app/api/trpc/[trpc]/route.ts   ← API handler with real headers
app/trpc-status/               ← test page (delete after confirming)

Updating layout.tsx

Before


  {children}
  

After


  
    {children}
    
  

Using the Generated Setup

Server Component – Prefetch Data

// app/page.tsx
import { HydrateClient, prefetch, trpc } from "@/trpc/server";
import { MyClient } from "./my-client";

export default function Page() {
  prefetch(trpc.greet.queryOptions({ name: "World" }));
  return (
    
      
    
  );
}

Client Component – Consume Data

// my-client.tsx
"use client";

import { useSuspenseQuery } from "@tanstack/react-query";
import { useTRPC } from "@/trpc/client";

export function MyClient() {
  const trpc = useTRPC();
  const { data } = useSuspenseQuery(
    trpc.greet.queryOptions({ name: "World" })
  );
  return {data.message};
}

Comparison with create-t3-app

  • create-t3-app is great for new projects.
  • create-trpc-setup works with existing projects, even if they already use Clerk, Shadcn UI, or custom providers. The command adds all necessary files without modifying your existing code.

Protected Procedure Helper

The generated init.ts includes a protectedProcedure that automatically throws an UNAUTHORIZED error when ctx.userId is missing:

export const protectedProcedure = t.procedure.use(({ ctx, next }) => {
  if (!ctx.userId) {
    throw new TRPCError({ code: "UNAUTHORIZED" });
  }
  return next({ ctx: { ...ctx, userId: ctx.userId } });
});

You can use it in any router:

getProfile: protectedProcedure.query(({ ctx }) => {
  return { userId: ctx.userId }; // guaranteed non‑null
}),
  • npm package:
  • GitHub repository:

If the CLI saved you time, consider starring the repository and sharing it with your team.

0 views
Back to Blog

Related posts

Read more »

Create AppStore Images with one liner

!Cover image for Create AppStore Images with one linerhttps://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2...