# tRPC — End-to-End Typesafe APIs for TypeScript > tRPC lets you build fully typesafe APIs without schemas, code generation, or runtime bloat. Share types between frontend and backend automatically. Works with Next.js, React, Vue, and more. ## Install Save as a script file and run: ## Quick Use ```bash # Install in your Next.js project npm install @trpc/server @trpc/client @trpc/react-query @trpc/next @tanstack/react-query zod # Create router # server/trpc.ts import { initTRPC } from '@trpc/server'; const t = initTRPC.create(); export const router = t.router; export const publicProcedure = t.procedure; ``` ## Intro **tRPC** allows you to easily build and consume fully typesafe APIs without schemas, code generation, or runtime bloat. It leverages TypeScript inference to automatically share types between your server and client — meaning every API call is type-checked end-to-end, with autocomplete and instant feedback on breaking changes. With 40K+ GitHub stars and MIT license, tRPC has revolutionized full-stack TypeScript development, eliminating the need for REST/GraphQL schemas and code generation in monorepo projects. ## What tRPC Does - **End-to-End Types**: Share TypeScript types between client and server automatically - **No Schema**: No protobuf, GraphQL schemas, or OpenAPI to maintain - **Input Validation**: Built-in Zod/Yup/Valibot validation - **Subscriptions**: WebSocket support for real-time updates - **Middleware**: Reusable logic for auth, logging, rate limiting - **Error Handling**: Typed error responses - **Batching**: Automatic request batching to reduce round-trips - **Framework Support**: Next.js, Express, Fastify, AWS Lambda, Cloudflare Workers - **Client Support**: React, Vue, vanilla TS, Svelte, SolidJS - **Streaming**: Server-sent events for streamed responses ## How It Works ``` Backend (TypeScript) Frontend (TypeScript) ────────────────── ────────────────── 1. Define procedures ──▶ 4. Import types 2. Define inputs 5. Call with autocomplete 3. Return data 6. Full type safety No schemas. No codegen. Just TypeScript. ``` ## Example: Next.js App ### 1. Define Router (server) ```typescript // server/trpc.ts import { initTRPC } from '@trpc/server'; const t = initTRPC.create(); export const router = t.router; export const publicProcedure = t.procedure; ``` ```typescript // server/routers/_app.ts import { z } from 'zod'; import { router, publicProcedure } from '../trpc'; export const appRouter = router({ // Query (GET equivalent) getUser: publicProcedure .input(z.object({ id: z.string() })) .query(async ({ input }) => { const user = await db.user.findUnique({ where: { id: input.id } }); return user; }), // Mutation (POST/PUT/DELETE equivalent) createPost: publicProcedure .input(z.object({ title: z.string().min(1).max(100), content: z.string().min(10), published: z.boolean().default(false), })) .mutation(async ({ input }) => { const post = await db.post.create({ data: input }); return post; }), // List with pagination listPosts: publicProcedure .input(z.object({ limit: z.number().min(1).max(100).default(10), cursor: z.string().nullish(), })) .query(async ({ input }) => { const posts = await db.post.findMany({ take: input.limit + 1, cursor: input.cursor ? { id: input.cursor } : undefined, orderBy: { createdAt: 'desc' }, }); let nextCursor: typeof input.cursor = undefined; if (posts.length > input.limit) { const nextItem = posts.pop(); nextCursor = nextItem?.id; } return { posts, nextCursor }; }), }); // Export type for client export type AppRouter = typeof appRouter; ``` ### 2. Client Setup ```typescript // lib/trpc.ts import { createTRPCReact } from '@trpc/react-query'; import type { AppRouter } from '../server/routers/_app'; export const trpc = createTRPCReact(); ``` ```typescript // pages/_app.tsx import { httpBatchLink } from '@trpc/client'; import { trpc } from '../lib/trpc'; function MyApp({ Component, pageProps }) { const [queryClient] = useState(() => new QueryClient()); const [trpcClient] = useState(() => trpc.createClient({ links: [ httpBatchLink({ url: '/api/trpc', }), ], }) ); return ( ); } ``` ### 3. Use in Components (Full Type Safety!) ```typescript // components/UserProfile.tsx import { trpc } from '../lib/trpc'; export function UserProfile({ userId }: { userId: string }) { // Fully typed query - autocomplete for 'getUser' const { data: user, isLoading } = trpc.getUser.useQuery({ id: userId }); // Fully typed mutation const createPost = trpc.createPost.useMutation({ onSuccess: () => { // Auto-refetch user data utils.getUser.invalidate({ id: userId }); }, }); if (isLoading) return
Loading...
; return (

{user?.name}

); } ``` **Magic**: If you rename a field in the backend, TypeScript immediately shows errors in every component using that field. ## Key Features ### Middleware ```typescript import { TRPCError } from '@trpc/server'; // Auth middleware const authMiddleware = t.middleware(async ({ ctx, next }) => { if (!ctx.user) { throw new TRPCError({ code: 'UNAUTHORIZED' }); } return next({ ctx: { ...ctx, user: ctx.user }, // Type narrowed to non-null }); }); // Protected procedure const protectedProcedure = t.procedure.use(authMiddleware); // Use in router export const appRouter = router({ getMyPosts: protectedProcedure.query(({ ctx }) => { return db.post.findMany({ where: { userId: ctx.user.id } }); }), }); ``` ### Subscriptions (WebSocket) ```typescript // Server import { observable } from '@trpc/server/observable'; import { EventEmitter } from 'events'; const ee = new EventEmitter(); export const appRouter = router({ onNewMessage: publicProcedure.subscription(() => { return observable<{ text: string }>((emit) => { const handler = (data: { text: string }) => emit.next(data); ee.on('message', handler); return () => ee.off('message', handler); }); }), }); // Client trpc.onNewMessage.useSubscription(undefined, { onData: (message) => { console.log('New message:', message.text); }, }); ``` ### Batching ```typescript // Multiple queries in one HTTP request httpBatchLink({ url: '/api/trpc', maxURLLength: 2083, // Auto-batch when possible }); ``` ```typescript // These three queries make 1 HTTP request instead of 3 const user = trpc.user.getById.useQuery({ id: '1' }); const posts = trpc.post.list.useQuery({ userId: '1' }); const stats = trpc.stats.getUser.useQuery({ id: '1' }); ``` ## tRPC vs Alternatives | Feature | tRPC | GraphQL | REST | gRPC | |---------|------|---------|------|------| | Type safety | End-to-end | Via codegen | Manual | Via codegen | | Schema | TypeScript | SDL | OpenAPI | Protobuf | | Setup | Very simple | Moderate | Simple | Complex | | Client generation | Not needed | Required | Optional | Required | | Runtime overhead | None | Resolver layer | None | Protobuf parser | | Subscriptions | Yes (WS) | Yes (WS) | SSE | Streaming | | Language support | TypeScript only | Many | Any | Many | | Best for | TS monorepos | Multi-language | Public APIs | Microservices | ## Framework Integrations ```typescript // Next.js import { createNextApiHandler } from '@trpc/server/adapters/next'; export default createNextApiHandler({ router: appRouter }); // Express import { createExpressMiddleware } from '@trpc/server/adapters/express'; app.use('/trpc', createExpressMiddleware({ router: appRouter })); // Fastify import { fastifyTRPCPlugin } from '@trpc/server/adapters/fastify'; server.register(fastifyTRPCPlugin, { prefix: '/trpc', trpcOptions: { router } }); // Cloudflare Workers import { fetchRequestHandler } from '@trpc/server/adapters/fetch'; export default { fetch(request: Request) { return fetchRequestHandler({ endpoint: '/trpc', req: request, router: appRouter }); }, }; ``` ## 常见问题 **Q: tRPC 和 GraphQL 怎么选?** A: 如果你用纯 TypeScript 且前后端在同一个 monorepo,tRPC 更简单更快。如果你需要多语言客户端、复杂查询灵活性或已有 GraphQL 生态,选 GraphQL。tRPC 适合 80% 的内部应用,GraphQL 适合公共 API。 **Q: 类型共享怎么实现的?** A: tRPC 使用 TypeScript 类型推断。你在 server 定义 router,export AppRouter 类型,client 导入这个类型。编译时 TypeScript 就知道所有 procedure 的输入输出类型——无需运行时开销或代码生成。 **Q: 适合移动端吗?** A: 可以用于 React Native。tRPC 也支持 vanilla TypeScript 客户端,可以在任何 TypeScript 环境使用。不支持非 TypeScript 客户端(Python/Go/Java)——如果需要,GraphQL 或 REST 更合适。 ## 来源与致谢 - GitHub: [trpc/trpc](https://github.com/trpc/trpc) — 40K+ ⭐ | MIT - 官网: [trpc.io](https://trpc.io) --- Source: https://tokrepo.com/en/workflows/baa87f69-3559-11f1-9bc6-00163e2b0d79 Author: Script Depot