Next Starter Logo

Get Started

Set up Next Starter locally: clone the repo, set environment variables, start PostgreSQL in Docker, run Prisma migrations, and start the Next.js dev server.

Prerequisites

Install these first:

  • Node.js 22.22.1 or newer, which is what package.json declares in its engines field. Next.js 16 itself only asks for 20.9, but Prisma refuses to install on anything below 20.19 or 22.12, and lint-staged, which the pre-commit hook runs, wants 22.22.1. The Docker image runs Node 24.
  • pnpm. The package manager this template uses.
  • Docker. Runs PostgreSQL on your machine through docker-compose.
  • Google OAuth credentials. Only social sign-in uses them, but the env schema wants both keys present either way.

1. Clone and install

git clone <your-repo-url> my-app
cd my-app
pnpm install

2. Configure environment

Copy the example file to create your local .env.

cp .env.example .env

.env.example ships with the app URLs pointed at localhost:3000 and a DATABASE_URL whose user, password, port, and database name match docker-compose.yml. Leave those as they are. Start with the auth secret:

pnpm dlx auth secret

Paste the output into BETTER_AUTH_SECRET.

A blank key breaks the page, not just the feature

lib/validations/env.ts calls envSchema.parse(process.env) the moment it loads, and lib/auth.ts imports it. The marketing layout reads the session, so a blank STRIPE_SECRET_KEY or STORAGE_S3_ENDPOINT throws on the homepage, the same as it does on billing or uploads. Search .env.example for ="", skip the commented-out lines, and that's your list of keys to fill.

The schema checks the shape of a value, never whether the credential works. So you can boot the app before signing up for five services: anything that parses as a URL for the two storage URLs, an ID starting with price_ for each Stripe price, 32 characters or more for the auth secret, and any non-empty string for the rest. Swap in real credentials before you touch the feature behind them.

One exception. lib/auth.ts sets requireEmailVerification: true and the code arrives by email, so SMTP2Go has to be real before you can verify your first account and sign in.

For the full variable list, see the Environment Variables reference.

ServiceWhat it powersGuide
Google OAuthSocial sign-inAuthentication
StripeSubscription billingBilling
SMTP2GoTransactional emailEmail
Cloudflare R2File uploads and avatarsFile Uploads
Cloudflare TurnstileBot protection on the contact formTurnstile

3. Start the database

PostgreSQL 18 comes up in Docker on port 5432.

docker-compose up -d

It creates a next_starter database with the postgres / postgres credentials that the default DATABASE_URL expects.

4. Run migrations

Two commands. The first creates your tables, the second generates the typed Prisma client.

pnpm prisma migrate dev
pnpm prisma generate

That second command isn't optional. In Prisma 7, migrate dev applies migrations but doesn't generate the client, so without it your code won't know about the new tables. The generated/ folder is gitignored too, so a fresh clone has no client at all until you run it.

To wipe the database and start fresh, run:

docker-compose down -v && docker-compose up -d && pnpm prisma migrate dev && pnpm prisma generate

5. Start the dev server

This runs Next.js at http://localhost:3000.

pnpm dev

The build script migrates, and Git push runs it

pnpm dev only starts Next.js. The build script runs prisma generate && next build && prisma migrate deploy, so a production deploy applies any pending migrations on its own.

And .husky/pre-push runs pnpm build too, so every git push applies migrations to whatever DATABASE_URL your shell or .env points at. Keep that pointed somewhere local, or drop the hook.

Preview email templates (optional)

The React Email preview runs at http://localhost:3001.

pnpm email

Edit any file in lib/email/ and the preview reloads right away.

What you should see

/ serves the marketing landing page. Register at /auth/register and enter the 6-digit code you receive. That verifies the account, signs you in, and drops you into the onboarding wizard at /onboarding. Finishing the wizard or hitting its skip button unlocks /dashboard.

To make yourself an admin, open the user table and set the role field on your row to "admin".

Next steps

On this page