Spin Up a Modern Full-Stack TypeScript App with create-t3-app
California man discovers this one weird trick for building modern full-stack applications in TypeScript without losing your sanity.
There’s a neat little tool out there called create-t3-app
—and if you’re even mildly allergic to complicated scaffolding, it might just become your new best friend. Picture it: spinning up a Next.js project, hooking in tRPC for type-safe APIs, sprinkling in Tailwind CSS for style, and adding Prisma for database interactions—all with a few commands and minimal fuss1.
Below, we’ll walk through how to get started, from the quick “npx” incantation to seeing your first type-safe API call in action.
Why Bother with create-t3-app?
If you find yourself wanting a React-based front end with Next.js, but also cringe at the thought of writing separate REST or GraphQL definitions (especially if you’re trying to preserve your code-based type safety across the stack), this is for you. The T3 stack is essentially a curated selection of modern TS-friendly tools:
- Next.js – Because SSR + React = synergy.
- TypeScript – Keep your type-safety close and your runtime errors even closer (actually fewer, hopefully).
- Tailwind CSS – No more naming CSS classes for 45 minutes; just sprinkle in utility classes.
- tRPC – A refreshing alternative to REST or GraphQL, letting you share types between front end and back end.
- Prisma – The ORM that feels like you’re writing normal TS code while storing data in a real database.
In short, it’s like a well-choreographed dance: each part knows its step, so you don’t trip over your partner’s feet.
Prerequisites: Yes, They’re Basic
Before you dive in, ensure you have:
- Node.js (preferably v18+)
- Your favorite package manager:
npm
,yarn
, orpnpm
Nothing too fancy. If you’re the sort to test new languages monthly, you probably already have these2.
Create a New Project
The main incantation:
npx create-t3-app@latest my-t3-app
You’ll be asked to pick which features you want. A typical combo might be:
tRPC, NextAuth.js, Tailwind CSS, Prisma
If you’re not sure, just pick them all. That’s half the fun. Once the process wraps up, hop into your new directory and start things:
cd my-t3-app npm install npm run dev
Lo and behold, you’ve got a Next.js dev server running at http://localhost:3000
. Open it up, admire that “Hello World” stand-in, and pat yourself on the back.
Understanding the Project Layout
Your brand-new repo might look like this:
my-t3-app/
├── src/
│ ├── pages/ # Next.js page routes
│ ├── server/ # tRPC, Prisma logic
│ ├── styles/ # Tailwind setup
│ ├── components/ # Reusable UI bits
│ ├── utils/ # Helpers for client & server
│ └── env.mjs # Environment variables
├── prisma/ # Database schema if Prisma is chosen
├── public/ # Static assets
├── .env # Private environment variables
├── package.json # Dependencies & scripts
└── tsconfig.json # TypeScript config
Don’t let the structure intimidate you—each folder has a fairly obvious purpose. The server/
directory is where backend logic lives, the pages/
directory is standard Next.js territory, and the prisma/
folder is your playground if you opted for database schema definitions.
Adding a Simple tRPC Procedure
Here’s the T3 special sauce: tRPC. Let’s say you want a quick “Hello World” route that can greet any visitor by name. Check out src/server/api/routers/example.ts
:
import { z } from \"zod\"; import { createTRPCRouter, publicProcedure } from \"~/server/api/trpc\"; export const exampleRouter = createTRPCRouter({ hello: publicProcedure .input(z.object({ name: z.string() })) .query(({ input }) => { return { greeting: `Hello, ${input.name}!` }; }), });
Then connect it in src/server/api/root.ts
:
import { exampleRouter } from \"./routers/example\"; import { createTRPCRouter } from \"./trpc\"; export const appRouter = createTRPCRouter({ example: exampleRouter, }); // Export type for usage in .ts files export type AppRouter = typeof appRouter;
And presto—you’ve got a type-safe endpoint waiting to be called.
Calling the API in React
You probably want to see “Hello, T3 user!” or something equally welcoming in your web app. For that, ensure @tanstack/react-query
is installed:
npm install @tanstack/react-query
Then, in src/pages/index.tsx
:
import { api } from \"~/utils/api\"; export default function Home() { const { data, isLoading } = api.example.hello.useQuery({ name: \"T3 User\" }); return ( <main className=\"flex min-h-screen items-center justify-center\"> <h1 className=\"text-3xl font-bold\"> {isLoading ? \"Loading...\" : data?.greeting} </h1> </main> ); }
Behind the scenes, your query calls the hello
tRPC procedure, retrieves the greeting, and displays it. No extra REST routes to define, no GraphQL resolvers—just type safety end to end.
Next Steps
After you confirm that your new T3 app is indeed greeting you properly, you can expand on it:
- Add more tRPC endpoints for your domain logic—stuff like fetching user data, performing database writes with Prisma, etc.
- Implement NextAuth for secure user sign-ins if you want out-of-the-box authentication.
- Configure Prisma to connect to your favorite database—PostgreSQL, MySQL, or even SQLite if you’re feeling scrappy.
The sky’s the limit. The T3 approach is about giving you a well-integrated foundation so you can build actual features without fiddling with config for days on end3.
Conclusion
create-t3-app
is the friend you wish you’d had earlier: it sets up a cohesive stack—Next.js + TypeScript + tRPC + Prisma + Tailwind—so you don’t have to piece it together from scratch. If you’re itching to code a new side project or spin up a prototype for your next big idea, give it a whirl. You might just find the sweet spot between dev speed and type safety.
Happy hacking—and remember: with tRPC, you can say goodbye to the dreaded mismatch of “front-end type vs. back-end type.” The T3 stack ensures your code is consistent from the database all the way up to the UI. Enjoy the synergy.
1 If “minimal fuss” can include the existential dread of reading new docs, that is.
2 Or you’re at least no stranger to “nvm use” incantations.
3 Because if you’re like me, you need to preserve your energy for the real puzzle: naming variables.
← Read more articles