Skip to content

Commit cfb640b

Browse files
Add Next.js + tRPC example (#8329)
1 parent 2b4f19c commit cfb640b

File tree

22 files changed

+902
-1
lines changed

22 files changed

+902
-1
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/bin/bash
2+
3+
set -eu
4+
5+
echo "🔍 Starting test setup for nextjs-trpc..."
6+
7+
echo "📂 Current working directory before REPO_ROOT: $(pwd)"
8+
echo "📁 Listing contents:"
9+
ls -la
10+
11+
REPO_ROOT="$(git rev-parse --show-toplevel)"
12+
echo "📌 Detected repo root: $REPO_ROOT"
13+
14+
cd "$REPO_ROOT/orm/nextjs-trpc"
15+
echo "📂 Changed directory to: $(pwd)"
16+
17+
echo "📦 Installing test deps..."
18+
npm install
19+
20+
# Go to Node script dir and install its deps
21+
NODE_SCRIPT_DIR="../../.github/get-ppg-dev"
22+
pushd "$NODE_SCRIPT_DIR" > /dev/null
23+
npm install --legacy-peer-deps
24+
25+
# Start Prisma Dev server
26+
LOG_FILE="./ppg-dev-url.log"
27+
rm -f "$LOG_FILE"
28+
touch "$LOG_FILE"
29+
30+
echo "🚀 Starting Prisma Dev in background..."
31+
node index.js >"$LOG_FILE" &
32+
NODE_PID=$!
33+
34+
# Wait for DATABASE_URL
35+
echo "🔎 Waiting for Prisma Dev to emit DATABASE_URL..."
36+
MAX_WAIT=60
37+
WAITED=0
38+
until grep -q '^prisma+postgres://' "$LOG_FILE"; do
39+
sleep 1
40+
WAITED=$((WAITED + 1))
41+
if [ "$WAITED" -ge "$MAX_WAIT" ]; then
42+
echo "❌ Timeout waiting for DATABASE_URL"
43+
cat "$LOG_FILE"
44+
kill "$NODE_PID" || true
45+
exit 1
46+
fi
47+
done
48+
49+
DB_URL=$(grep '^prisma+postgres://' "$LOG_FILE" | tail -1)
50+
export DATABASE_URL="$DB_URL"
51+
echo "✅ DATABASE_URL: $DATABASE_URL"
52+
53+
popd > /dev/null
54+
55+
# Run migrations
56+
npx prisma migrate dev --name init
57+
58+
# Start the app
59+
echo "🚀 Starting Next.js app..."
60+
npm run dev &
61+
pid=$!
62+
63+
sleep 15
64+
65+
# Check frontend (Next defaults to port 3000)
66+
echo "🔎 Verifying root frontend route..."
67+
curl --fail 'http://localhost:3000/'
68+
69+
# Cleanup
70+
echo "🛑 Shutting down Next.js app (PID $pid) and Prisma Dev (PID $NODE_PID)..."
71+
kill "$pid"
72+
kill "$NODE_PID"
73+
wait "$NODE_PID" || true
74+
75+

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# projects-specific .gitignore).
55

66
node_modules/
7-
generated/prisma/
7+
generated/
88
yarn-error.log/
99
vendor/
1010
tmp/

orm/nextjs-trpc/.gitignore

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.*
7+
.yarn/*
8+
!.yarn/patches
9+
!.yarn/plugins
10+
!.yarn/releases
11+
!.yarn/versions
12+
13+
# testing
14+
/coverage
15+
16+
# next.js
17+
/.next/
18+
/out/
19+
20+
# production
21+
/build
22+
23+
# misc
24+
.DS_Store
25+
*.pem
26+
27+
# debug
28+
npm-debug.log*
29+
yarn-debug.log*
30+
yarn-error.log*
31+
.pnpm-debug.log*
32+
33+
# env files (can opt-in for committing if needed)
34+
.env*
35+
36+
# vercel
37+
.vercel
38+
39+
# typescript
40+
*.tsbuildinfo
41+
next-env.d.ts

orm/nextjs-trpc/README.md

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
# Next.js + tRPC + Prisma Todo App
2+
3+
A simple, clean todo application showcasing the integration of Next.js App Router, tRPC, and Prisma.
4+
5+
## Tech Stack
6+
7+
- **Next.js 15** - React framework with App Router
8+
- **tRPC 11** - End-to-end typesafe APIs
9+
- **Prisma** - Database ORM
10+
- **React Query** - Data fetching and caching
11+
- **TypeScript** - Type safety
12+
- **Tailwind CSS** - Styling
13+
14+
## Project Structure
15+
16+
```
17+
src/
18+
├── app/
19+
│ ├── api/trpc/[trpc]/route.ts # tRPC API handler
20+
│ ├── layout.tsx # Root layout
21+
│ ├── page.tsx # Home page
22+
│ └── todos/page.tsx # Todo list page
23+
├── components/
24+
│ └── providers.tsx # React Query & tRPC providers
25+
├── lib/
26+
│ ├── db/
27+
│ │ └── index.ts # Prisma client
28+
│ └── trpc/
29+
│ ├── context.ts # tRPC context
30+
│ ├── index.ts # tRPC initialization
31+
│ └── routers/
32+
│ ├── index.ts # Main router
33+
│ └── todo.ts # Todo routes
34+
└── utils/
35+
└── trpc.ts # tRPC React client
36+
37+
prisma/
38+
├── schema.prisma # Prisma schema
39+
└── generated/ # Generated Prisma client
40+
```
41+
42+
## Getting Started
43+
44+
### 1. Install Dependencies
45+
46+
```bash
47+
bun install
48+
```
49+
50+
### 2. Set Up Database
51+
52+
Create a new [Prisma Postgres](https://www.prisma.io/docs/postgres/overview) database by executing:
53+
54+
```terminal
55+
npx prisma init --db
56+
```
57+
58+
If you don't have a [Prisma Data Platform](https://console.prisma.io/) account yet, or if you are not logged in, the command will prompt you to log in using one of the available authentication providers. A browser window will open so you can log in or create an account. Return to the CLI after you have completed this step.
59+
60+
Once logged in (or if you were already logged in), the CLI will prompt you to:
61+
1. Select a **region** (e.g. `us-east-1`)
62+
1. Enter a **project name**
63+
64+
After successful creation, you will see output similar to the following:
65+
66+
<details>
67+
68+
<summary>CLI output</summary>
69+
70+
```terminal
71+
Let's set up your Prisma Postgres database!
72+
? Select your region: ap-northeast-1 - Asia Pacific (Tokyo)
73+
? Enter a project name: testing-migration
74+
✔ Success! Your Prisma Postgres database is ready ✅
75+
76+
We found an existing schema.prisma file in your current project directory.
77+
78+
--- Database URL ---
79+
80+
Connect Prisma ORM to your Prisma Postgres database with this URL:
81+
82+
prisma+postgres://accelerate.prisma-data.net/?api_key=...
83+
84+
--- Next steps ---
85+
86+
Go to https://pris.ly/ppg-init for detailed instructions.
87+
88+
1. Install and use the Prisma Accelerate extension
89+
Prisma Postgres requires the Prisma Accelerate extension for querying. If you haven't already installed it, install it in your project:
90+
npm install @prisma/extension-accelerate
91+
92+
...and add it to your Prisma Client instance:
93+
import { withAccelerate } from "@prisma/extension-accelerate"
94+
95+
const prisma = new PrismaClient().$extends(withAccelerate())
96+
97+
2. Apply migrations
98+
Run the following command to create and apply a migration:
99+
npx prisma migrate dev
100+
101+
3. Manage your data
102+
View and edit your data locally by running this command:
103+
npx prisma studio
104+
105+
...or online in Console:
106+
https://console.prisma.io/{workspaceId}/{projectId}/studio
107+
108+
4. Send queries from your app
109+
If you already have an existing app with Prisma ORM, you can now run it and it will send queries against your newly created Prisma Postgres instance.
110+
111+
5. Learn more
112+
For more info, visit the Prisma Postgres docs: https://pris.ly/ppg-docs
113+
```
114+
115+
</details>
116+
117+
Locate and copy the database URL provided in the CLI output. Then, create a `.env` file in the project root:
118+
119+
Now, paste the URL into it as a value for the `DATABASE_URL` environment variable. For example:
120+
121+
```bash
122+
# .env
123+
DATABASE_URL=prisma+postgres://accelerate.prisma-data.net/?api_key=ey...
124+
```
125+
126+
### 3. Initialize Database
127+
128+
```bash
129+
# Generate Prisma client
130+
bun run db:generate
131+
132+
# Push schema to database
133+
bun run db:push
134+
```
135+
136+
### 4. Run Development Server
137+
138+
```bash
139+
bun run dev
140+
```
141+
142+
Open [http://localhost:3001](http://localhost:3001) in your browser.
143+
144+
## Available Scripts
145+
146+
- `bun run dev` - Start development server
147+
- `bun run build` - Build for production
148+
- `bun run start` - Start production server
149+
- `bun run db:generate` - Generate Prisma client
150+
- `bun run db:push` - Push schema changes to database
151+
- `bun run db:studio` - Open Prisma Studio
152+
- `bun run db:migrate` - Create database migration
153+
154+
## How It Works
155+
156+
### tRPC Setup
157+
158+
The tRPC setup follows the official Next.js App Router pattern:
159+
160+
1. **Server-side** (`src/lib/trpc/`):
161+
- `index.ts` - Initializes tRPC with context
162+
- `routers/` - Defines API endpoints
163+
- `context.ts` - Creates request context
164+
165+
2. **Client-side** (`src/utils/trpc.ts`):
166+
- Creates tRPC React client using `@trpc/react-query`
167+
168+
3. **API Route** (`src/app/api/trpc/[trpc]/route.ts`):
169+
- Handles HTTP requests to tRPC endpoints
170+
171+
### Making Requests
172+
173+
```tsx
174+
import { trpc } from '@/utils/trpc';
175+
176+
function TodoList() {
177+
// Query
178+
const todos = trpc.todo.getAll.useQuery();
179+
180+
// Mutation
181+
const createTodo = trpc.todo.create.useMutation({
182+
onSuccess: () => {
183+
utils.todo.getAll.invalidate();
184+
},
185+
});
186+
187+
return (
188+
<div>
189+
{todos.data?.map(todo => (
190+
<div key={todo.id}>{todo.text}</div>
191+
))}
192+
</div>
193+
);
194+
}
195+
```
196+
197+
## Database Schema
198+
199+
The app uses a simple Todo model:
200+
201+
```prisma
202+
model Todo {
203+
id Int @id @default(autoincrement())
204+
text String
205+
completed Boolean @default(false)
206+
}
207+
```
208+
209+
## Learn More
210+
211+
- [tRPC Documentation](https://trpc.io)
212+
- [Next.js Documentation](https://nextjs.org/docs)
213+
- [Prisma Documentation](https://www.prisma.io/docs)
214+
- [React Query Documentation](https://tanstack.com/query)

orm/nextjs-trpc/components.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"$schema": "https://ui.shadcn.com/schema.json",
3+
"style": "new-york",
4+
"rsc": false,
5+
"tsx": true,
6+
"tailwind": {
7+
"config": "",
8+
"css": "src/index.css",
9+
"baseColor": "neutral",
10+
"cssVariables": true,
11+
"prefix": ""
12+
},
13+
"aliases": {
14+
"components": "@/components",
15+
"utils": "@/lib/utils",
16+
"ui": "@/components/ui",
17+
"lib": "@/lib",
18+
"hooks": "@/hooks"
19+
},
20+
"iconLibrary": "lucide"
21+
}

orm/nextjs-trpc/next.config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import type { NextConfig } from "next";
2+
3+
const nextConfig: NextConfig = {
4+
typedRoutes: true,
5+
};
6+
7+
export default nextConfig;

0 commit comments

Comments
 (0)