Stop configuring. Start building.
Full-stack Next.js starter with auth, database, and type-safe APIs already set up.
- Next.js 15 - React framework with App Router
- TypeScript - Type safety
- tRPC - End-to-end type-safe APIs
- Drizzle ORM - Type-safe database queries
- PostgreSQL - Database
- Better Auth - Authentication (magic link + Google OAuth)
- Tailwind CSS - Styling
- Bun - Runtime and package manager
-
Clone and install
git clone <repo-url> cd next-starterpack bun install
-
Set up environment variables
cp .env.example .env
Fill in:
DATABASE_URL- PostgreSQL connection stringGOOGLE_CLIENT_ID&GOOGLE_CLIENT_SECRET- Google OAuth credentialsBETTER_AUTH_SECRET- Random secret (runopenssl rand -base64 32)BETTER_AUTH_URL- Your app URL (e.g.,http://localhost:3000)RESEND_API_KEY- Resend API key for emails
-
Set up database
bun db:push
-
Run dev server
bun dev
Visit http://localhost:3000
src/
├── app/ # Next.js pages (App Router)
├── components/ # React components
│ ├── ui/ # Reusable UI components
│ └── features/ # Feature-specific components
├── server/ # Backend code
│ ├── routers/ # tRPC API routes
│ └── services/ # Business logic
└── lib/ # Utils, DB, auth config
- Authentication - Magic link email + Google OAuth out of the box
- Type-safe APIs - tRPC with automatic type inference
- Database - Drizzle ORM with PostgreSQL, migrations ready
- UI Components - Radix UI + Tailwind, light/dark mode
- Email - React Email templates with Resend
bun dev # Start dev server
bun build # Build for production
bun start # Start production server
bun lint # Lint and format code
# Database
bun db:push # Push schema changes to database
bun db:generate # Generate migration files
bun db:migrate # Run migrations
bun db:studio # Open database GUIEdit src/server/routers/[name].ts:
import { router, protectedProcedure } from "../trpc";
export const myRouter = router({
myQuery: protectedProcedure.query(({ ctx }) => {
// Access user via ctx.user
return { message: "Hello!" };
}),
});Add to src/server/routers/_app.ts
import { trpc } from "@/lib/trpc/react";
function MyComponent() {
const { data } = trpc.myRouter.myQuery.useQuery();
return <div>{data?.message}</div>;
}