Next.js Starter Kit
A production-grade Next.js 14+ template built on the App Router that saves you the first two weeks of every project. Comes pre-configured with TypeScript strict mode, Prisma ORM with migration scripts, authentication via NextAuth.js, server-side rendering and incremental static regeneration patterns, API route handlers with validation middleware, and Vercel deployment configs with preview environments. Clone it, set your environment variables, and deploy — your infrastructure is handled so you can ship features on day one.
Key Features
- App Router Architecture — Layouts, loading states, error boundaries, and parallel routes using Next.js 14+ conventions
- Prisma ORM Integration — Database schema, seed scripts, migration workflow, and type-safe queries with connection pooling
- Authentication System — NextAuth.js with credentials, Google, and GitHub providers; session management and protected routes
- SSR + ISR Patterns — Server components for dynamic data, ISR with revalidation tags for content pages, and streaming with Suspense
- API Route Handlers — Type-safe route handlers with Zod validation, error handling middleware, and rate limiting
-
Vercel Deployment —
vercel.jsonconfig, preview environments per branch, edge middleware, and environment variable management -
SEO & Metadata — Dynamic
generateMetadata, Open Graph images, JSON-LD structured data, and sitemap generation - Developer Experience — ESLint + Prettier configs, Husky pre-commit hooks, path aliases, and VS Code settings
Quick Start
# Clone and install
npx degit your-org/nextjs-starter-kit my-app
cd my-app
npm install
# Set up environment
cp .env.example .env.local
# Edit .env.local with your database URL and auth secrets
# Initialize database
npx prisma migrate dev --name init
npx prisma db seed
# Start development
npm run dev
Your app is running at http://localhost:3000 with authentication, database, and API routes ready.
Architecture / How It Works
nextjs-starter-kit/
├── app/
│ ├── (auth)/ # Login, register route group
│ ├── (dashboard)/ # Protected dashboard with layout
│ ├── api/ # NextAuth + versioned API routes
│ ├── layout.tsx # Root layout with providers
│ └── error.tsx # Global error boundary
├── components/ # ui/ primitives + features/ components
├── lib/ # auth.ts, db.ts, validations.ts
├── prisma/ # schema.prisma, seed.ts, migrations/
├── next.config.ts
└── vercel.json
Usage Examples
Server Component with Data Fetching
// app/(dashboard)/page.tsx
import { db } from '@/lib/db';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { redirect } from 'next/navigation';
export default async function DashboardPage() {
const session = await getServerSession(authOptions);
if (!session) redirect('/login');
const stats = await db.order.aggregate({
where: { userId: session.user.id },
_sum: { amount: true },
_count: true,
});
return (
<div className="grid grid-cols-3 gap-6">
<StatCard title="Total Orders" value={stats._count} />
<StatCard title="Revenue" value={`$${stats._sum.amount?.toFixed(2)}`} />
</div>
);
}
API Route with Validation
// app/api/v1/users/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { z } from 'zod';
import { db } from '@/lib/db';
const createUserSchema = z.object({
name: z.string().min(2).max(100),
email: z.string().email(),
role: z.enum(['user', 'admin']).default('user'),
});
export async function POST(request: NextRequest) {
try {
const data = createUserSchema.parse(await request.json());
const user = await db.user.create({ data });
return NextResponse.json(user, { status: 201 });
} catch (error) {
if (error instanceof z.ZodError) return NextResponse.json({ errors: error.flatten() }, { status: 400 });
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
}
}
Configuration
Environment Variables (.env.example)
DATABASE_URL="postgresql://user:password@localhost:5432/myapp"
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="YOUR_SECRET_HERE" # openssl rand -base64 32
GOOGLE_CLIENT_ID="YOUR_GOOGLE_CLIENT_ID"
GOOGLE_CLIENT_SECRET="YOUR_GOOGLE_CLIENT_SECRET"
Next.js Configuration (next.config.ts)
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
experimental: {
typedRoutes: true, // type-safe Link hrefs
},
images: {
remotePatterns: [
{ protocol: 'https', hostname: 'images.example.com' },
],
},
logging: {
fetches: { fullUrl: true }, // log fetch URLs in development
},
};
export default nextConfig;
Best Practices
-
Use Server Components by default — only add
'use client'when you need interactivity, event handlers, or browser APIs - Colocate data fetching — fetch data in the component that needs it; Next.js deduplicates and caches requests automatically
-
Use route groups for layouts —
(auth)and(dashboard)groups share layouts without affecting URL structure -
Keep Prisma client a singleton — the included
lib/db.tsprevents creating multiple connections during hot reload - Validate at the boundary — parse request bodies with Zod in API routes; trust the typed data downstream
-
Use
revalidateTag— prefer tag-based revalidation over time-based for content that changes on write operations
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
| Prisma client not found after install |
prisma generate not run |
Add "postinstall": "prisma generate" to package.json scripts |
| NextAuth session is null in Server Component | Using useSession instead of getServerSession
|
Call getServerSession(authOptions) in Server Components |
| Hydration mismatch errors | Client component renders differently than server | Wrap browser-only code in useEffect or use suppressHydrationWarning
|
| Vercel deploy fails with Prisma | Prisma engine binary not included in build | Add prisma generate to Vercel build command: prisma generate && next build
|
This is 1 of 11 resources in the Frontend Developer Pro toolkit. Get the complete [Next.js Starter Kit] with all files, templates, and documentation for $49.
Or grab the entire Frontend Developer Pro bundle (11 products) for $129 — save 30%.
Top comments (0)