Setting Up a Next.js 15 Project
A proper setup from the start prevents configuration headaches later. Next.js 15 ships with TypeScript, ESLint, and Tailwind CSS support out of the box.
Creating a New Project
npx create-next-app@latest my-app
The interactive prompt will ask:
Would you like to use TypeScript? Yes
Would you like to use ESLint? Yes
Would you like to use Tailwind CSS? Yes
Would you like your code inside a `src/` directory? No
Would you like to use App Router? Yes
Would you like to use Turbopack for next dev? Yes
Would you like to customize the import alias? Yes (@/*)
Project Structure
After scaffolding, the key directories are:
my-app/
├── app/ # App Router pages and layouts
│ ├── layout.tsx # Root layout (wraps every page)
│ ├── page.tsx # Home page (/)
│ └── globals.css # Global styles
├── components/ # Shared React components
├── lib/ # Utilities and shared logic
├── public/ # Static assets
├── next.config.ts # Next.js configuration
├── tailwind.config.ts # Tailwind configuration
└── tsconfig.json # TypeScript configuration
next.config.ts
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
experimental: {
ppr: true, // Partial Prerendering
},
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'images.unsplash.com',
},
],
},
};
export default nextConfig;
Environment Variables
# .env.local (never commit this file)
DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
NEXTAUTH_SECRET="your-secret-here"
NEXTAUTH_URL="http://localhost:3000"
Access in server code only:
// app/lib/db.ts
const dbUrl = process.env.DATABASE_URL; // server-side only
// Expose to client with NEXT_PUBLIC_ prefix
const apiUrl = process.env.NEXT_PUBLIC_API_URL; // available in browser
Running the Development Server
npm run dev # Start with Turbopack (fast HMR)
npm run build # Production build
npm run start # Start production server
npm run lint # Run ESLint
Always use npm run dev with Turbopack enabled for dramatically faster rebuilds during development.