Before touching tRPC, you need to master modern TypeScript, API contract concepts, and the differences between RPC, REST, and GraphQL. In this episode you will also set up Node.js, create a TypeScript project, install @trpc/server, @trpc/client, and zod, and verify your first installation.

Welcome to the Learning tRPC series! This series will take you to mastery of tRPC — the TypeScript RPC library that lets servers and clients share types directly, without codegen and without schema duplication. There are 19 episodes in total, organized into six phases, from core concepts all the way to production readiness.
But before writing your first router, there are some core skills and software you must have. Why are pre-requisites important? Because tRPC's main strength is end-to-end TypeScript type inference. If you don't yet understand generics or have never seen TypeScript code using static types, most of tRPC's magic will feel like sorcery.
Episode 0 is your roadmap: making sure your core skills are in place, setting up Node.js and TypeScript, installing the tRPC packages, and running your first verification. Once this episode is done, the rest of the series can be followed comfortably.
tRPC is built on top of TypeScript. Make sure you are comfortable with primitive types, interfaces, union types, and especially generics — because tRPC routers internally use generics to infer types from the server down to the client. Here is a pattern that will appear often:
function ambil<T>(items: T[], index: number): T {
return items[index];
}
const nama = ambil(["andi", "budi"], 0);
const angka = ambil([1, 2, 3], 1);Notice that nama is typed as string and angka is typed as number — the types are inferred automatically without explicit annotation. This is the same fundamental principle tRPC uses to infer procedure types from the server to the client.
Also understand the API contract-first concept: defining the shape of your data before implementation. tRPC does not require JSON Schema, but it works very well with validators like zod that describe the input and output shape of procedures. Later in episode 3, you will see that the input schema becomes the single source of truth on both sides.
In general, you need to understand three API paradigms:
getUser.GET /users/1.tRPC is a modern form of RPC that leverages TypeScript. We will examine the detailed comparison in episode 1.
tRPC runs on top of Node.js. Install the latest Node.js LTS — the npm package manager comes bundled with it automatically. For this series we will use npm, but pnpm and bun are also fully supported.
node --version
npm --versionMake sure your Node version is at least 18. If it is not yet installed, visit the official Node.js website and download the LTS version, or use Node Version Manager to switch versions easily.
The editor you must have is one that supports TypeScript well — VS Code is the most common choice. For testing your API later in episode 4, prepare a browser for the frontend and an HTTP client such as Postman, or simply curl in the terminal.
For service integration in episode 10 and later deployment, Docker is optional but very helpful. Verify it with the following command if you decide to use it:
docker --versionStart by creating a project directory and initializing npm:
mkdir belajar-trpc
cd belajar-trpc
npm init -y
npm install typescript @types/node zod
npm install --save-dev tsx
npx tsc --initnpx tsc --init creates a tsconfig.json file with default configuration. Change "target" to "ES2020" or newer, and make sure "strict" is set to true — strict mode catches many bugs before runtime.
Now install the core tRPC packages. For the generic server and client:
npm install @trpc/server @trpc/clientThese two packages are enough to build an API and consume it without React. In episode 4 we will add @trpc/react-query and @tanstack/react-query for integration with a React frontend.
Before moving on to episode 1, create a verify.ts file with the following contents to make sure everything is installed correctly:
import { initTRPC } from "@trpc/server";
import { createCallerFactory } from "@trpc/server";
import { z } from "zod";
const t = initTRPC.create();
const appRouter = t.router({
halo: t.procedure
.input(z.object({ nama: z.string() }))
.query(({ input }) => `Halo, ${input.nama}!`),
});
const createCaller = createCallerFactory(appRouter);
const caller = createCaller({});
const hasil = await caller.halo({ nama: "Arman" });
console.log(hasil);Run it with tsx:
npx tsx verify.tsIf it prints Halo, Arman!, your environment is ready. The createCallerFactory(appRouter) command creates a direct caller inside the server — we will examine the details of routers and procedures starting from episode 3.
Here is a summary of the pre-requisites you have prepared in episode 0:
halo router invoked through a caller.If anything is missing, stop and complete it before continuing. A strong foundation will make the next 18 episodes feel much lighter.
In episode 0 you have prepared the footing for the entire series: understanding the TypeScript skills required, setting up Node.js and tooling, installing the tRPC packages, and verifying your first router that produces output.
Key takeaways:
@trpc/server and @trpc/client are the two core packages.createCallerFactory.In the next episode, episode 1, we will discuss history, background, and why you need tRPC — from its origins in the TypeScript community, its evolution from simple RPC to full-stack zero-boilerplate, to its comparison with REST and GraphQL. Make sure your environment is ready, because the Learning tRPC journey is just beginning!