- Node.js 24
- Corepack and pnpm 11.24.0
- Docker with Docker Compose
package.json pins pnpm and the supported Node range. pnpm-workspace.yaml records the dependencies permitted to run install-time build scripts.
corepack enable
pnpm install --frozen-lockfile
cp example.env .env
docker compose up -d db
pnpm db:deploy
pnpm devThe app runs at http://localhost:3000. PostgreSQL listens on localhost:5432 and persists in the db_data Docker volume. These credentials are disposable development defaults; never reuse them for a hosted database.
| Variable | Required | Browser-visible | Notes |
|---|---|---|---|
BETTER_AUTH_SECRET |
Yes | No | At least 32 high-entropy characters; keep stable across restarts |
DATABASE_URL |
Yes | No | PostgreSQL URL; hosted connections must use TLS |
APP_URL |
Outside local dev | No | Canonical origin; local development defaults to http://localhost:3000 |
Both Next.js and the Prisma CLI load an ignored .env. Never add real values to example.env.
Better Auth owns email-and-password registration, credentials, and database-backed sessions. The handler is mounted at /api/auth/[...all]. The application does not need an external auth dashboard, custom auth DNS, or a user-sync webhook.
Generate a local secret once:
openssl rand -base64 32Store it only in the ignored .env. Public signup requires name, username, email, and a password of 12 to 128 characters. Email verification and password reset remain disabled until a mail provider is configured. Do not use throwaway passwords: there is no reset path yet.
The database contains preserved Clerk-era users without credential accounts. Better Auth cannot sign those users in, and a same-email signup must not claim them. Recover them later through verified password reset or transfer content to an explicitly identified new user.
The schema is in prisma/schema.prisma, CLI configuration is in prisma.config.ts, and committed migrations are in prisma/migrations.
Apply the existing migration set without creating a new migration:
pnpm db:deployWhen intentionally changing the schema locally:
pnpm exec prisma migrate dev --name describe_the_change
pnpm db:generateCommit the schema and migration together. Hosted releases use only pnpm db:deploy; never use migrate dev or db push against hosted data.
Useful local commands:
pnpm db:generate
pnpm exec prisma studio
docker compose logs db
docker compose stop dbStopping Compose keeps db_data. Removing that volume deletes local data and requires explicit intent.
pnpm lint
pnpm typecheck
pnpm format:check
pnpm buildThere is no automated test suite yet. Manually verify any affected path:
- Visit
/,/posts, an article,/about, and/contact-uswhile signed out. - Create an account at
/sign-up, sign out, and sign back in at/sign-in. - Create a Markdown post at
/create. - Like, bookmark, and comment on it; repeated like/bookmark requests must not create duplicates.
- Check Posts, Likes, and Bookmarks at
/profile/<username>. - Confirm only the author sees the delete control and that server authorization rejects another user.
- Delete the post and submit the contact form, including one forced error path.
- Check
/robots.txtand/sitemap.xmlagainst the configuredAPP_URL.
- Profile likes and bookmarks are public.
- Post URLs use database cuid values despite the route parameter being named
slug. - New registrations require usernames. Legacy users may still lack one, so profile links remain conditional.
- Email verification and password reset are not configured. Public signups can enter addresses they do not own.
- Public feedback is validated but has no application-level rate limiter. Add one if abuse becomes material.