Next.js and MongoDB, where the data layer is the product.
A monorepo where the app only calls a data layer. That's where the single MongoDB client lives, with every schema, every query and the authorization — ownership built into the filter itself.
Use it when
You're starting a Next.js product on MongoDB and want sign-in, per-user queries, indexes and migrations done right from day one.
On Postgres and need background jobs? template-next-supabase instead →What's included
Done from the start.
One client
The MongoClient is created in one place, and the database is never exported — the app only gets functions.
Ownership in the filter
Every function takes a session, and ownership sits inside the query, not in an if afterwards.
Sign-in
Auth.js v5 with an emailed code (Resend), plus GitHub or Google if you add the keys.
Three shapes per entity
Input (untrusted), the stored document and what leaves the layer — so a new secret field can't leak by default.
Indexes and migrations
Indexes declared in code and applied from CI, migrations tracked. Never at app start.
Tests without a cluster
The data layer is tested against an in-memory MongoDB with Vitest.
The principles
The rules it keeps.
- 1
One client, one place for collection names.
- 2
The database isn't exported — only functions and types.
- 3
Every function takes a session, never a user id.
- 4
"use server" belongs in actions.ts, never in the data layer.
- 5
Cursor pagination with a cap. No skip.
- 6
Indexes are applied from CI, never when the app starts.
Get started
pnpm install
cp .env.example apps/web/.env.local
cp .env.example packages/db/.env
# set MONGODB_URI, MONGODB_DB, AUTH_SECRET
pnpm db:migrate
pnpm db:indexes
pnpm devStructure
packages/db/ @ketryon/db — the MongoClient, the schemas, every query
packages/auth/ @ketryon/auth — Auth.js v5: email code + OAuth
apps/web/ Next.js 16 app; calls the DAL, owns no database codeEnvironment variables
- MONGODB_URI
- MONGODB_DB
- AUTH_SECRET
Only three are required. Without a Resend key, the sign-in code is printed to the server log in development.
Good to know
- Needs Node 20.19 or later, pnpm 10 and a MongoDB you can reach.
- Type-check and lint pass with Next 16.4, React 19.3, MongoDB driver 7.7 and Zod 4.6.
Built with
- Next.js 16
- React 19
- MongoDB driver 7
- Auth.js v5
- Zod 4
- Resend
- Tailwind CSS 4
- Vitest
More templates
template-next-supabase
MITNext.js and Supabase, where a typed data layer owns every query and every authorization check.
Next.js 16 · React 19 · Supabase
Read more →template-monorepo
MITA Next.js web app, an Express API and Inngest background jobs sharing one database schema.
Next.js 15 · React 19 · Clerk
Read more →template-backend
MITA REST API in Express and TypeScript with sign-in, Postgres, Redis and validation in place.
Express 5 · TypeScript · Clerk
Read more →template-gateway
MITA Next.js layer between your apps and an existing API, keeping the API key on the server.
Next.js 15 · React 19 · TypeScript
Read more →template-react-native
MITAn iOS and Android app in Expo with navigation, light and dark themes and a typed API client.
Expo SDK 54 · React Native 0.81 · React 19
Read more →
Let's build
the next thing.
You talk to me, not a salesperson. The first call is free.
— Kenny
psst, it takes 15 min
Write, and I reply the same working day.