Next.jsReactAdmin dashboardSaaSStarter

dimah-starter — Next.js Admin dashboard Template

By dimah-kz

A server-first Turborepo starter for multi-tenant SaaS, including a Next.js dashboard, Better Auth authentication, Drizzle database, and S3 storage.

Explore the design

Compare the page layouts and mobile experience. Open any screenshot for a closer look.

2 previews
Desktop homepage1 / 2
Desktop captureTop of page

Actual screenshot captured by the server browser.

All pages & views 2

Screenshots show visual appearance; interactive behavior may differ.

Recorded 2026-10-11View source

What stands out

A quick read of the recorded project description.

01

Server-first: sessions are read in RSCs, writes are performed via Server Actions, and the UI contains no client-side data layer

02

Turborepo multi-package structure: api, auth, db, storage, email, i18n, and ui split by responsibility

03

Built-in email/password authentication, email verification, password reset, organizations, members, invitations, and platform administrators

04

Uses the Next.js Cache Components model, managing caches via cacheTag, cacheLife, and updateTag

05

Integrates Drizzle database migrations and S3-compatible dimah-s3 storage uploads

06

The i18n package provides UI copy and locale settings, with RTL support from day one

Template Details

dimah-starter is a Turborepo-based multi-tenant SaaS starter whose product interface is built server-first: sessions are read in RSCs via auth.api.getSession, lists come from tagged caches, and write operations such as authentication, organizations, and uploads are performed through Server Actions, with no authClient or client-side data layer in the UI. apps/web is the Next.js product application, containing the dashboard, authentication, and platform administration; packages are split into api (oRPC), auth (Better Auth server-side), db (Drizzle schema, client, and migrations), storage (dimah-s3 storage), email (Resend transactional email), i18n (UI copy and locale settings), and ui (shadcn / ReUI / Dimah components). apps/mobile and apps/extension are placeholders, sharing through packages rather than cross-app references.

Built in are email/password sign-up and sign-in, email verification, password reset, organizations, members, invitations, platform administrators, and S3 uploads. OAuth does not yet appear in the interface; the product oRPC in @repo/api currently has only a health.ping stub, so you need to add procedures under src/routers/health/ yourself and then call them from Server Actions via createRouterClient. apps/web uses Next.js Cache Components configuration (cacheComponents and partialPrefetching in next.config.ts); cache reads use 'use cache', cacheTag, and cacheLife, same-user writes use updateTag, and sessions are not cached.

Running requires Node ≥ 22, pnpm 12, PostgreSQL, and an S3-compatible dimah-s3 storage bucket (e.g., R2). For production, note: BETTER_AUTH_URL should be set to the public origin, and localhost is trusted only in non-production environments; serverless environments should use a pooled DATABASE_URL; getSession may use a cookie cache of up to 5 minutes, so after a ban or role change a user may still appear signed in until the cache expires; authentication rate-limit counters are stored in Postgres and apply only to Better Auth HTTP routes under /api/auth, not to Server Actions; in production, RESEND_API_KEY and EMAIL_FROM must be configured, otherwise in development the email content is printed to the server logs.

Next.jsReactAdmin dashboardSaaSStarter

Is it right for your project?

Use Cases

  • Building a multi-tenant SaaS admin dashboard that needs organizations, members, and an invitation model
  • Next.js projects centered on server-side rendering and Server Actions that avoid a client-side data layer
  • Dashboard products that need email/password authentication, email verification, and password reset
  • Admin applications that need S3-compatible object storage upload capabilities
  • As a starting point for a Turborepo multi-package structure, later extending to mobile or browser extensions

Suitable For

  • Developers familiar with Next.js, React, and Turborepo
  • Teams that need a multi-tenant organization and member management dashboard
  • Projects that prefer a server-first architecture and do not want to introduce a client-side data layer SDK
  • Teams that can prepare PostgreSQL and an S3-compatible storage bucket themselves

Getting started & customization

Use these recorded setup notes alongside the repository instructions for your chosen version.

  1. 1

    Environment requirements: Node ≥ 22, pnpm 12, PostgreSQL, and an S3-compatible dimah-s3 storage bucket (e.g., R2)

  2. 2

    Copy .env.example to .env and fill in DATABASE_URL, BETTER_AUTH_*, and optionally GOOGLE_*, S3_*, RESEND_*, EMAIL_FROM

  3. 3

    Run pnpm --filter @repo/db db:migrate to apply migrations, then pnpm dev to start web and db together

  4. 4

    In production, set BETTER_AUTH_URL to the public origin; for serverless deployments, use a pooled DATABASE_URL

  5. 5

    In production, configure RESEND_API_KEY and EMAIL_FROM; otherwise in development the email content is printed to the server logs

Read repository instructions

License & source material

Usage conditions & limitations

Free to use · keep license notice

This listing covers the free version under the MIT license in the public repository; the free scope is the code of that version and does not mean external services or third-party assets are free.

Must comply with when using

  • You may use, modify, commercialize, and distribute the code of this version for free.
  • When distributing copies or substantial portions of the code, retain the original author's copyright notice and the full MIT license notice.
  • The code is provided as is; warranties and limitations of liability are governed by the original license and applicable law.

Additional costs & items to verify

  • Demo images, fonts, icons, and other third-party assets must be checked against their respective licenses and cannot be judged solely by the code's MIT license.
  • External services such as domains, hosting, databases, payments, or AI may incur separate charges.
  • Running requires an S3-compatible dimah-s3 storage bucket (e.g., Cloudflare R2), which is an external service dependency you must prepare and pay for yourself.
  • Environment requirements are Node ≥ 22, pnpm 12, PostgreSQL, and dimah-s3 storage, all of which you must deploy or provision yourself.
  • In production, Resend's RESEND_API_KEY and EMAIL_FROM must be configured, meaning it depends on the external Resend email service.
  • The GOOGLE_* environment variables are optional and used for Google-related integrations; you must apply for the corresponding credentials yourself.
  • OAuth sign-in is not yet implemented in the interface and must be developed and integrated yourself.
  • The product oRPC is currently only a health.ping stub; business endpoints must be added by you under src/routers/health/.
  • Serverless deployments must use a pooled DATABASE_URL; direct connections on 5432 will exhaust connections under burst traffic.
  • The session cookie cache lasts up to 5 minutes, so after a ban or role change a user may still appear signed in until the cache expires.
  • Authentication rate limiting applies only to Better Auth HTTP routes under /api/auth and does not cover Server Actions.
  • localhost:3000 is trusted only in non-production environments; in production, BETTER_AUTH_URL must be set separately.
  • When Resend keys are not configured, development prints email content (including verification links) to the server logs.
View Original Text Basis

Permission is hereby granted, free of charge

Original License Text

dimah-s3 storage (S3-compatible bucket, e.g. R2)

Original README

Node ≥ 22 · pnpm 12 · PostgreSQL · dimah-s3 storage

Original README

set `RESEND_API_KEY` and `EMAIL_FROM` in production

Original README

optional GOOGLE_*

Original README

Not in the UI yet: OAuth.

Original README

Product oRPC is a `health.ping` stub in `@repo/api`

Original README

use a **pooled** `DATABASE_URL` (Neon pooler, PgBouncer, Supabase pooler). Direct `5432` will exhaust connections under bursty functions.

Original README

`getSession` may use a cookie for up to **5 minutes**. After a ban or role change, the affected user can still look signed-in until that cache expires.

Original README

That limiter applies to Better Auth HTTP routes (`/api/auth`), not Server Actions.

Original README

`http://localhost:3000` is trusted only outside production.

Original README

Without a key, development prints the message (including the link) to the server log.

Original README
https://github.com/dimah-kz/dimah-starter/blob/main/LICENSEhttps://github.com/dimah-kz/dimah-starter/blob/main/README.md

Compiled by DeepSeek based on repository license and README ·2026-10-11. Results only cover the materials read; dependencies, images, fonts, and subsequent term changes are subject to their respective original texts.

Project checks & description sources

Template Information

Source platforms
GitHub
Documentation and maintenance reference score
More documented · 88 / 100
Technologies
Next.js · React
Website type
Admin dashboard · SaaS · Starter
How this score is calculated

Our heuristic uses license records (up to 30), a demo link (12), a preview (10), stars (15), recorded maintenance (15), description completeness (8), feature records (5) and classification data (5). It is not a code, security or performance test, or a Google score. A link does not establish tested functionality.

What to verify for this project

Repository update recorded
2026-10-11
Screenshot last checked
2026-10-11

A demo link is listed. Check it with your own content and viewport sizes; its presence does not confirm that forms, authentication or payments work.

The catalog identifies Next.js as the primary stack. Check the actual dependency manifest and lockfile for versions and hosting requirements. These notes use recorded metadata, not a code audit or a deployment test.

Use a selection guide →

How this description was prepared

AI-assisted description based on catalog records and repository material. Repository authors are not automatically the reviewers of this description.

Review declaration: [email protected] · 2026-10-11

Inspect the recorded source material

SHA-256: 3cf293fc6e631b86c87580de91f4bc127fcae1e25fb16a8f477867cdbffe9dc5

2026-10-11T06:26:23.182Z

Source file / repository
# dimah-starter

A **server-first Turborepo starter** for multi-tenant SaaS — Next.js dashboard, Better Auth, Postgres, and [dimah-s3](https://dimah-s3.vercel.app) storage. Shared packages are ready for a mobile or extension app later.

The product surface is server-first, not just login: session in RSC, lists from tagged cache, writes (auth, orgs, uploads) as Server Actions. No `authClient` and no client data layer in the UI.

**[Use this template](https://github.com/dimah-kz/dimah-starter/generate)**

## Why server-first

| Typical SaaS kit                         | This starter                              |
| ---------------------------------------- | ----------------------------------------- |
| Client SDK + React Query / providers     | RSC session via `auth.api.getSession`     |
| Client mutations, then refetch           | Server Actions → `auth.api` → `updateTag` |
| Drop-in widgets for auth, storage, menus | Your chrome: sidebar, org switcher, menus |
| Copy and locale owned by the kit         | `@repo/i18n` + RTL from day one           |

## Cache Components

`apps/web` runs the Next.js 16.4 Cache Components model (`cacheComponents: true` and `partialPrefetching: true` in `next.config.ts`). That is framework config, not an extra library.

- Cached reads: `'use cache'` + `cacheTag` + `cacheLife` in `get-*.ts`
- Same-user writes: `updateTag` in the mutating Server Action
- Session is never cached

## Structure

```
dimah-starter/
├── apps/
│   └── web/                 # Next.js product (dashboard, auth, admin)
├── packages/
│   ├── api/                 # Product oRPC (caller + /api/rpc)
│   ├── auth/                # Better Auth server
│   ├── db/                  # Drizzle schema, client, migrations
│   ├── storage/             # dimah-s3 storage
│   ├── email/               # Resend transactional email
│   ├── i18n/                # UI messages & locale
│   └── ui/                  # shadcn / ReUI / Dimah
├── tooling/
│   ├── eslint-config/
│   └── typescript-config/
└── docs/agents/             # Contributor / agent guides
```

`apps/mobile` and `apps/extension` are reserved slots — share through packages, not across apps.

## Quick start

Node ≥ 22 · pnpm 12 · PostgreSQL · dimah-s3 storage (S3-compatible bucket, e.g. R2)

```bash
pnpm install
cp .env.example .env          # DATABASE_URL, BETTER_AUTH_*, optional GOOGLE_*, S3_*, RESEND_*, EMAIL_FROM
pnpm --filter @repo/db db:migrate
pnpm dev                     # web + db
```

→ [http://localhost:3000](http://localhost:3000)

| Command                             | What it does     |
| ----------------------------------- | ---------------- |
| `pnpm --filter web dev`             | Run the web app  |
| `pnpm build` / `lint` / `typecheck` | Quality gates    |
| `pnpm --filter @repo/db db:migrate` | Apply migrations |

## Included vs add when you need it

Ships with email/password sign-in and sign-up, email verification, password reset, organizations, members, invitations, platform admin, and S3 uploads.

Not in the UI yet: OAuth. Product oRPC is a `health.ping` stub in `@repo/api` (`src/routers/health/`) — add procedures there, then call them from Server Actions with `createRouterClient`.

## Production

- **Trusted origins** — `http://localhost:3000` is trusted only outside production. Set `BETTER_AUTH_URL` to the public origin.
- **Postgres on serverless** — use a **pooled** `DATABASE_URL` (Neon pooler, PgBouncer, Supabase pooler). Direct `5432` will exhaust connections under bursty functions.
- **Session cookie cache** — `getSession` may use a cookie for up to **5 minutes**. After a ban or role change, the affected user can still look signed-in until that cache expires.
- **Auth rate limit** — counters live in Postgres so they survive serverless. That limiter applies to Better Auth HTTP routes (`/api/auth`), not Server Actions. Email verification and password-reset links use those routes.
- **Email** — set `RESEND_API_KEY` and `EMAIL_FROM` in production. Without a key, development prints the message (including the link) to the server log.

Conventions: [`AGENTS.md`](./AGENTS.md). MIT — see [LICENSE](./LICENSE).
Report a correction

Explore similar templates

Compare previews and descriptions within the same stack and category.