Project Setup
You can't learn Next.js by reading about it. You need a working application you can break, fix, and extend. This lesson gets you from zero to deployed in under 10 minutes, with a real app running on Vercel and automatic preview deployments on every push.
Every lesson in this course builds on this foundation. Get this right, and the rest will flow naturally.
Outcome
A working local development environment and a Vercel-connected repository that deploys previews on every push.
What You're Getting with the Starter
This isn't a blank canvas. You're deploying a working application with:
- Two Next.js apps:
apps/web(main app) andapps/blog(blog app) - Shared packages:
packages/api(data fetching) andpackages/ui(components) - Working routes: Home page, blog listing, dynamic post pages
- API layer: Blog posts, categories, and gallery data ready to use
Your job throughout this course is to extend and modify this foundation, not build from scratch. This mirrors real-world development where you'll rarely start with an empty folder.
Understanding the Dual-App Architecture
This starter contains two Next.js applications running side-by-side. This isn't accidental - it teaches you real-world monorepo patterns where teams share code but deploy independently.
nextjs-foundations/
├── apps/
│ ├── web/ # Main marketing + dashboard app
│ │ └── src/app/ # Port 3000 (Vercel-deployed)
│ │
│ └── blog/ # Content-focused blog app
│ └── src/app/ # Port 3001
│
└── packages/
├── api/ # Shared data fetching
└── ui/ # Shared components (shadcn)
Which app should I work in?
| App | Purpose | Port | When You'll Use It |
|---|---|---|---|
apps/web | Main marketing and dashboard app | 3000 | Most lessons (95% of your work) |
apps/blog | Content-focused blog app | 3001 | Dynamic Routing, Section 4 (Multi-app deployments) |
Why two apps instead of one?
Real companies organize apps this way:
- Separation of concerns: Marketing team owns
web, content team ownsblog - Independent deployment: Deploy blog changes without touching web
- Shared packages: Both apps import from
@repo/uiand@repo/api
When lessons switch to apps/blog, you'll see a callout like this:
In Section 4, you'll connect both apps using Next.js rewrites, so users see a unified site (vercel.com/blog and vercel.com) while each app deploys independently behind the scenes.
Fast Track
- Click the Deploy Button below to copy and deploy
- Install Vercel CLI:
pnpm i -g vercel && vercel login - Clone your repo and link:
git clone ... && cd nextjs-foundations && vercel link - Install and run:
pnpm i && pnpm dev
Step 1: Deploy to Vercel
Click this button to copy the repository to your GitHub account and deploy to Vercel in one step:
What just happened:
- The starter repo was copied to your GitHub account
- Vercel deployed both apps automatically
- GitHub integration was configured for preview deployments
Step 2: Install the Vercel CLI
The Vercel CLI connects your local environment to your Vercel project. You'll use it throughout this course to check deployments, pull environment variables, and manage your project.
# Install globally
pnpm add -g vercel
# Authenticate (opens browser)
vercel loginStep 3: Clone and Install
Now get the code on your machine:
# Clone YOUR copy (replace with your GitHub username)
git clone https://github.com/YOUR_USERNAME/nextjs-foundations
cd nextjs-foundations
# Install dependencies
pnpm iStep 4: Link Your Project
Navigate to the web app and connect it to the Vercel project you deployed:
cd apps/web
vercel linkSelect your team and the nextjs-foundations project when prompted. When asked "Would you like to pull your environment variables?", answer Yes.
This creates:
- A
.verceldirectory linking your local app to the deployed project - A
.env.localfile with real working values:
NEXT_PUBLIC_APP_NAME="ACME Corporation"
INTERNAL_CONFIG="server-only-value"The deploy button baked these defaults into your Vercel project, so you get actual values immediately. No manual setup required.
Return to the monorepo root for the remaining steps:
cd ../..Step 5: Run Locally
Start the development server:
pnpm devYou'll see the Turborepo TUI (terminal UI) showing both apps:
┌ @repo/web#dev ─────────────────────────────────────────────────┐
│ ▲ Next.js 16.1.1 (Turbopack) │
│ - Local: http://localhost:3000 │
│ ✓ Ready in 436ms │
└────────────────────────────────────────────────────────────────┘
┌ @repo/blog#dev ────────────────────────────────────────────────┐
│ ▲ Next.js 16.1.1 (Turbopack) │
│ - Local: http://localhost:3001 │
│ ✓ Ready in 436ms │
└────────────────────────────────────────────────────────────────┘
Use arrow keys to switch between apps and see their logs.
Step 6: Verify Preview Deployments
Make a small change and push to confirm the deployment pipeline works:
# Create a branch
git checkout -b test-preview
# Make any small change (add a comment, fix a typo)
echo "// test" >> apps/web/src/app/page.tsx
# Commit and push
git add -A
git commit -m "test: verify preview deployment"
git push -u origin test-previewCheck the deployment status from your terminal:
vercel listYou should see output like this:
> Deployments for yourteam/nextjs-foundations
Age Deployment Status Environment
1m https://nextjs-foundations-abc123.vercel.app ● Ready Preview
5m https://nextjs-foundations-xyz789.vercel.app ● Ready Production
The Preview deployment is your branch. Production is the main branch.
After confirming the preview works, clean up:
git checkout main
git branch -D test-preview
git push origin --delete test-previewDone-When
- Vercel CLI installed and authenticated (
vercel whoamishows your username) - Project linked (
vercel linkcompleted,.verceldirectory exists) pnpm devruns both apps (web on :3000, blog on :3001)- http://localhost:3001 shows blog posts from the API layer
- Pushing a branch triggers a Vercel preview deployment (
vercel listshows it)
Explore What You Got
Before moving on, take 2 minutes to look around:
| Path | What's There |
|---|---|
apps/web/src/app/page.tsx | Web app home page (Server Component) |
apps/web/src/app/env-demo/page.tsx | Environment variables demo |
apps/blog/src/app/page.tsx | Blog listing page |
apps/blog/src/app/[slug]/page.tsx | Dynamic blog post route |
packages/api/src/blog.ts | Blog data fetching functions |
packages/ui/src/components/button.tsx | Shared Button component (shadcn) |
You don't need to understand all of this yet. Just know it exists. We'll explore each piece in upcoming lessons.
Troubleshooting
Port already in use
Error: listen EADDRINUSE: address already in use :::3000Fix: Kill the process or use a different port:
lsof -ti:3000 | xargs kill -9
# or
PORT=3001 pnpm devModule not found
Error: Cannot find module 'zod'Fix: Clean install:
rm -rf node_modules .next apps/*/.next
pnpm installpnpm not recognized
Fix: Install pnpm with corepack:
corepack enable
corepack prepare pnpm@latest --activateWrong Node.js version
WARN Unsupported engine: wanted: {"node":"24.x"}Fix: Use fnm to manage Node versions:
# Install fnm (macOS/Linux)
curl -fsSL https://fnm.vercel.app/install | bash
# Install and use Node 24
fnm install 24
fnm use 24Vercel deployment fails
Check these in your Vercel project settings:
- Build Command: Should be auto-detected as
pnpm buildorturbo build - Root Directory: Leave empty (monorepo root)
- Node.js Version: 24.x
If builds fail with type errors, run pnpm build locally first to see the actual error.
I'm setting up a Next.js 16 project and getting an error.
**Error message:**
```
___PASTE_ERROR_MESSAGE_HERE___
```
**My environment:**
- Node version: _____ (run `node -v` to check)
- Package manager: _____ (pnpm/npm/yarn)
- OS: _____ (macOS/Windows/Linux)
**What I was trying to do:**
___DESCRIBE_WHAT_YOU_WERE_DOING___
Example: "Running pnpm install" or "Starting dev server with pnpm dev"
Help me understand what's causing this error and how to fix it.What's Next
You now have a working Next.js application deployed to production. In the next lesson, you'll learn how the App Router organizes your code: how page.tsx, layout.tsx, and folder structure map to URLs.
Was this helpful?