AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
A starter template for Next.js projects using Better Auth and Prisma.
Developer toolsTypeScript · CSSGitHub @laguilloOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Modern Next.js 16 & React 19 template integrated with Better Auth, Prisma, and Shadcn UI for building secure, scalable web apps.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
This is a robust and modern template for Next.js applications, pre-configured with advanced authentication, database, and ready-to-use UI components. Designed to accelerate the development of secure and scalable web applications.Read the full README ↗A production-ready Next.js 16 SaaS starter: authentication, PostgreSQL, admin and user dashboards, and transactional emails, already wired with Better Auth, Prisma and shadcn/ui. Deploy it to Railway in one click, or run it locally in a few minutes.
One click → live app. The Railway button provisions PostgreSQL, wires
DATABASE_URL, applies migrations and gives you a public HTTPS URL. OnlyRESEND_API_KEYand Google OAuth keys are needed afterwards to enable emails and social login.
src/generated/prisma/api/health, restart on failure, and migrations applied on every start@prisma/adapter-pg driver adapterFollow these steps to set up the project in your local environment.
git clone https://github.com/laguillo/nextjs-better-auth-prisma-template.git
cd nextjs-better-auth-prisma-template
We recommend using Bun for a faster experience:
bun install
Create a .env file in the project root and configure the following variables:
# Database (PostgreSQL)
DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"
# Better Auth
BETTER_AUTH_SECRET="your_super_secure_secret" # Generate with: openssl rand -base64 32
BETTER_AUTH_URL="http://localhost:3000"
NEXT_PUBLIC_BASE_URL="http://localhost:3000" # In production: your public domain (also used for OG image, sitemap and robots URLs)
# OAuth Providers (Google)
GOOGLE_CLIENT_ID="your_google_client_id"
GOOGLE_CLIENT_SECRET="your_google_client_secret"
# Email (Resend)
RESEND_API_KEY="re_123456789"
EMAIL_SENDER_NAME="Your App"
EMAIL_SENDER_ADDRESS="[email protected]"
| Variable | What it is for |
|---|---|
DATABASE_URL | PostgreSQL connection string used by Prisma. |
BETTER_AUTH_SECRET | Secret Better Auth uses to sign sessions. |
BETTER_AUTH_URL | Public URL of the app (Better Auth's base URL). |
NEXT_PUBLIC_BASE_URL | Public URL used for the OG image, sitemap, robots and password-reset links. Resolved at build time; falls back to BETTER_AUTH_URL. |
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET | Google OAuth credentials. In Google Cloud Console add http://localhost:3000/api/auth/callback/google as an authorized redirect URI (use your production domain there when you deploy). |
RESEND_API_KEY | Resend API key, used for verification and password-reset emails. |
EMAIL_SENDER_NAME, EMAIL_SENDER_ADDRESS | The "From" of those emails. The address must be on a domain you have verified in Resend. |
Run Prisma migrations to create the tables:
bunx prisma migrate dev
This will also generate the Prisma client in src/generated/prisma automatically.
No PostgreSQL installed?
bunx prisma dev --detachstarts an isolated local Postgres without Docker. Copy thepostgres://…URL it prints intoDATABASE_URL, then run the command above.
bun dev
Open http://localhost:3000 in your browser.
There is no UI to promote a user, so do it once by hand:
/signup. Email/password accounts must verify their email before they can sign in. With a working RESEND_API_KEY you get the verification email; without one, open bunx prisma studio and set emailVerified to true on your user (signing in with Google skips this step).role to admin./admin.Route protection has two layers:
src/proxy.ts redirects visitors without a session cookie from /dashboard and /admin to /login. It only checks that the cookie exists, so it is a convenience, not a security boundary.src/app/(protected)/ in the gate of its panel:// src/app/(protected)/admin/reports/page.tsx
import { AdminGate } from '@/components/admin/auth-gate';
export default function ReportsPage() {
return <AdminGate>{/* admin-only content */}</AdminGate>;
}
Use DashboardGate (from @/components/dashboard/auth-gate) for pages under /dashboard.
A layout cannot protect its pages: Next.js renders route segments independently of the layout, and a page's output can still reach the browser in the RSC payload even if the layout replaces it with an error screen. That is why the check lives in the page.
Cache Components and Partial Prefetching are enabled in next.config.ts, so every route must be prerenderable. Reading cookies(), headers(), await params or await searchParams outside a <Suspense> boundary fails bun run build with "Next.js encountered uncached or runtime data during prerendering" (next dev only shows it in the browser overlay and still serves the page, so bun run build is the reliable check).
The fix is to move the request-time read into a small async component wrapped in <Suspense> with a skeleton fallback. The auth pages, reset-password and the protected layouts are working examples. See the caching guide and the error page.
src/lib/constants.ts. The deploy link carries the template author's referral code, so replace it with your own if you publish a fork.src/app/(public)/page.tsx and src/components/landing/. Every deploy button takes a placement that becomes utm_content, so Railway's stats show which button converts.defaultTheme in src/app/layout.tsx (dark by default; enableSystem keeps the "System" option working).src/components/emails/, sending in src/lib/auth.ts.src/lib/auth.ts. Email verification is required to sign in (requireEmailVerification).├── prisma/
│ ├── schema.prisma # Database schema
│ └── migrations/ # Migration history
├── public/ # Static files (favicons, tech-stack logo SVGs)
├── railway.toml # Railway healthcheck and restart policy
├── src/
│ ├── app/ # Application routes (App Router)
│ │ ├── (auth)/ # Authentication routes
│ │ │ ├── login/
│ │ │ ├── signup/
│ │ │ ├── forgot-password/
│ │ │ └── reset-password/
│ │ ├── (public)/ # Public landing page
│ │ ├── (protected)/ # Routes requiring a session
│ │ │ ├── dashboard/ # User panel
│ │ │ └── admin/ # Admin panel (requires role === "admin")
│ │ ├── api/ # API Routes (Better Auth handler, health check)
│ │ ├── opengraph-image.tsx # Generated social preview image
│ │ ├── robots.ts # robots.txt
│ │ └── sitemap.ts # sitemap.xml
│ ├── components/ # React components
│ │ ├── admin/ # Admin panel components (+ auth-gate and layout/ subfolder)
│ │ ├── dashboard/ # User panel components (+ auth-gate and layout/ subfolder)
│ │ ├── emails/ # Email templates (React Email)
│ │ ├── landing/ # Public landing page components
│ │ ├── shared/ # Shared components (theme toggle, skeletons, ...)
│ │ └── ui/ # Base components (Shadcn UI on Base UI)
│ ├── generated/ # Generated code
│ │ └── prisma/ # Generated Prisma client (gitignored)
│ ├── hooks/ # Custom React Hooks
│ ├── lib/ # Utilities and configuration
│ │ ├── auth.ts # Better Auth configuration (server-only)
│ │ ├── auth-client.ts # Better Auth client (Client Components)
│ │ ├── constants.ts # Site name/URL and tracked Railway deploy link
│ │ ├── prisma.ts # Prisma client singleton
│ │ └── utils.ts # Helper functions
│ ├── proxy.ts # Optimistic redirect for /dashboard and /admin
│ ├── server/ # Server Actions
│ └── types/ # TypeScript type definitions
bun dev: Starts the development serverbun run build: Generates the Prisma client and builds the application for production (use bun run build, not bun build, which is Bun's own bundler)bun start: Applies pending migrations (prisma migrate deploy) and starts the production serverbunx tsc --noEmit: Type-checks the projectbun lint: Runs ESLint. It currently fails because typescript-eslint does not support TypeScript 7 yet (tracking issue); use bunx tsc --noEmit in the meantimebunx prisma studio: Opens Prisma Studio to visually manage the databasebunx prisma migrate dev: Creates and applies database migrationsbunx prisma generate: Regenerates the Prisma client after schema changes without creating a migrationThe project includes the following models:
role defaults to userClick the Deploy on Railway button at the top. The template provisions PostgreSQL and wires DATABASE_URL; bun start applies pending migrations on every start, and railway.toml configures the /api/health healthcheck (it runs SELECT 1 against the database) and restarts the service on failure.
After the first deploy:
BETTER_AUTH_SECRET, BETTER_AUTH_URL and NEXT_PUBLIC_BASE_URL are set. The last one is read at build time, so redeploy after changing it.RESEND_API_KEY (and EMAIL_SENDER_NAME / EMAIL_SENDER_ADDRESS) to enable verification and password-reset emails.GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET, and register https://<your-domain>/api/auth/callback/google as a redirect URI in Google Cloud Console.This project is under the MIT license.