The stack, with nothing hidden
The template is built from common tools you can read, change and deploy yourself. Nothing is locked behind a proprietary service, and you keep control of your data.
Layer
What's included
Why this choice
Application
Next.js 16 (App Router) and React 19
Pages rendered on the server, fast, one language from client to server
Interface
Tailwind CSS 4, forms with react-hook-form and zod
Consistent styling, data validated on both client and server
Sign-in
Better Auth: email and password, two-factor authentication, Google and GitHub
Secure accounts, email confirmation required before the first sign-in, rate-limited attempts
Payments
Stripe (SDK 23): Checkout, customer portal, signed webhooks
Subscriptions and one-time purchases, one active subscription per person (duplicates are cancelled and refunded)
Data
PostgreSQL 17 and Prisma 7
Standard relational database, versioned migrations in the repository
Resend: confirmation, welcome, password reset, billing
Reliable sending, with a key limited to sending
Languages
English and French (next-intl)
Every text lives in a translation file
Quality
Vitest (unit tests), Playwright (end-to-end tests), GitHub Actions CI
Lint, tests and build on every change
Deployment
Docker Compose, with Dokploy or Vercel
One image, one database and the variables: the same deployment on your server or with a host
Operations
Encrypted PostgreSQL backup every night, copied off the server, alerts by email or webhook, personal data export
Restore your data, know when a backup fails, answer a data access request
What you keep. The code is yours: change it, deploy it where you want, add your own pages and tables. The data stays in your PostgreSQL database.
What is not included
To be honest about the limits:
- no detailed error tracking: errors are logged and alerted, but not grouped or kept in a dashboard
- no point-in-time restore: backups are daily, so up to one day of data can be lost after a failure
- no teams or organisations: an account belongs to one person
- refunding a subscription does not remove access: cancel the subscription as well