Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

create-fastnext

A CLI tool to scaffold a production-ready full-stack turborepo monorepo with authentication, database, and multi-platform support — all wired up and ready to go.

npx @danoweibo/create-fastnext my-app
# or
pnpm dlx @danoweibo/create-fastnext my-app

What you get

A turborepo monorepo with 5 apps and 5 shared packages, fully configured with auth, database, linting, and typed environment variables out of the box.

Apps

App Framework Port Purpose
apps/web Next.js 16 (Pages Router) 5000 Consumer web app — sign in, sign up, dashboard
apps/admin Next.js 16 (App Router) 5100 Admin dashboard — role-gated, admin-only access
apps/app Vite + React 5200 Lightweight generic app
apps/mobile Expo 55 + React Native 8081 Mobile app — iOS and Android
apps/server Fastify 5 8080 API server — auth handler + protected routes

Packages

Package Purpose
@{name}/auth Shared Better Auth configuration with Drizzle adapter
@{name}/db Drizzle ORM schema + Supabase-ready migrations
@{name}/env Type-safe environment variables per app (t3-env)
@{name}/ui Shared shadcn/ui component library (Tailwind 4)
@{name}/config Shared TypeScript base configuration

Stack

Core

  • Monorepo — Turborepo + pnpm workspaces
  • Language — TypeScript throughout
  • Linting & Formatting — Biome (replaces ESLint + Prettier)

Backend

  • Server — Fastify 5
  • Auth — Better Auth with email/password, username, admin plugin, bearer token, and Expo support
  • Database — Drizzle ORM + PostgreSQL (Supabase)
  • Env validation — t3-env with Zod

Frontend (Web)

  • Framework — Next.js 16
  • Styling — Tailwind CSS 4 + shadcn/ui
  • Forms — TanStack Form + Zod validation
  • Themes — next-themes (dark/light mode)

Frontend (Mobile)

  • Framework — Expo 55 + React Native
  • Styling — Tailwind CSS 4 via Uniwind
  • Components — heroui-native
  • Variants — tailwind-variants
  • Auth storage — expo-secure-store

Auth features

Better Auth is pre-configured across all platforms with the following out of the box:

  • Email + password sign in and sign up
  • Username support with normalization, min/max length, reserved name list, and display name validation
  • Admin plugin — role-based access, user banning with custom message
  • Bearer token — for mobile API requests (React Native doesn't use browser cookies)
  • Expo plugin — deep link auth for React Native with secure token storage
  • Trusted origins — all app URLs pre-configured for local and production
  • Cross-domain cookiessameSite: none, secure: true for Vercel → Render setup

Role system

Two roles are supported out of the box: user (default) and admin.

  • apps/admin — only allows sign in for users with role: "admin". Non-admin accounts are detected after sign-in and redirected to the consumer app.
  • apps/web + apps/mobile — accessible by all authenticated users regardless of role.

To promote a user to admin, run directly on the database:

UPDATE "user" SET "role" = 'admin' WHERE "email" = 'your@email.com';

API routes

The server ships with three tiers of test routes that demonstrate the auth-gating pattern:

Route Auth Role Used by
GET /api/test/items None Public apps/app, apps/mobile
POST /api/testuser/create Required Any user apps/web, apps/mobile
GET /api/testuser/read Required Any user apps/web, apps/mobile
PUT /api/testuser/update Required Any user apps/web, apps/mobile
DELETE /api/testuser/delete Required Any user apps/web, apps/mobile
POST /api/testadmin/create Required Admin only apps/admin
GET /api/testadmin/read Required Admin only apps/admin
PUT /api/testadmin/update Required Admin only apps/admin
DELETE /api/testadmin/delete Required Admin only apps/admin

These are wired up with working UI in each app — create, read, update, delete with live responses displayed. Replace them with your real business logic.


Getting started

Prerequisites

  • Node.js 18+
  • pnpm 11+
  • A Supabase project

Scaffold

pnpm create fastnext my-app
cd my-app

The CLI will ask:

  1. Initialize a git repository? (default: Yes)
  2. Install dependencies with pnpm? (default: Yes)

Database setup

  1. Open your Supabase project → SQL Editor
  2. Run the schema from packages/db/src/schema/auth.ts (or use the generated SQL in Supabase)
  3. Copy your Supabase connection string (Transaction pooler recommended) and update apps/server/.env:
DATABASE_URL=postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres

Environment variables

Each app has a pre-populated .env for local development and .env.production for deployment. The only values you need to fill in locally are:

apps/server/.env

BETTER_AUTH_SECRET=<auto-generated by CLI>
BETTER_AUTH_URL=http://localhost:8080
CORS_ORIGIN=http://localhost:5000,http://localhost:5100,http://localhost:5200
DATABASE_URL=your-supabase-connection-string

apps/admin/.env

NEXT_PUBLIC_SERVER_URL=http://localhost:8080
NEXT_PUBLIC_ENTRY_URL=http://localhost:5000

apps/web/.env

NEXT_PUBLIC_SERVER_URL=http://localhost:8080

apps/mobile/.env

EXPO_PUBLIC_SERVER_URL=http://<your-local-ip>:8080

Note: Mobile can't use localhost — use your machine's local IP address (ipconfig on Windows, ifconfig on Mac/Linux).

apps/app/.env

VITE_SERVER_URL=http://localhost:8080

Start developing

pnpm dev:admin      # admin + server
pnpm dev:web        # web + server
pnpm dev:mobile     # mobile + server (Expo)
pnpm dev:api        # server only

pnpm dev:admin+core # admin + web + server
pnpm dev:core+ticket # web + app + server
pnpm dev:app        # mobile only (no server)

Deployment

Recommended setup

App Platform
apps/server Render
apps/admin Vercel
apps/web Vercel
apps/app Vercel
Database Supabase
Mobile Expo EAS

Important: Vercel and Render are on different domains. The template uses Next.js rewrites (/api/* → Render) to avoid cross-domain cookie issues. This is pre-configured in apps/admin/next.config.ts and apps/web/next.config.ts.

Render (server)

Set these environment variables in your Render service:

BETTER_AUTH_SECRET=<your-secret>
BETTER_AUTH_URL=https://<your-render-service>.onrender.com
CORS_ORIGIN=https://<your-web>.vercel.app,https://<your-admin>.vercel.app,https://<your-app>.vercel.app
DATABASE_URL=<your-supabase-connection-string>
NODE_ENV=production

Vercel (admin, web, app)

Set these in each Vercel project's environment variables:

Admin:

NEXT_PUBLIC_SERVER_URL=https://<your-render-service>.onrender.com
NEXT_PUBLIC_ENTRY_URL=https://<your-web>.vercel.app

Web:

NEXT_PUBLIC_SERVER_URL=https://<your-render-service>.onrender.com

App:

VITE_SERVER_URL=https://<your-render-service>.onrender.com

Custom domain tip: If you own a domain (e.g. myapp.com), point all services at subdomains (api.myapp.com, app.myapp.com, admin.myapp.com). Set domain: ".myapp.com" in the Better Auth cookie config and the rewrite workaround becomes unnecessary.


Development scripts

Script What it runs
pnpm dev All apps (via Turborepo)
pnpm dev:admin apps/admin + apps/server
pnpm dev:web apps/web + apps/server
pnpm dev:ticket apps/app + apps/server
pnpm dev:mobile apps/mobile + apps/server
pnpm dev:admin+core apps/admin + apps/web + apps/server
pnpm dev:core+ticket apps/web + apps/app + apps/server
pnpm dev:api apps/server only
pnpm dev:app apps/mobile only
pnpm build Build all apps
pnpm check-types Type check all packages
pnpm check Biome check + auto-fix (safe)
pnpm lint:fix Biome check + auto-fix (including unsafe — sorts Tailwind classes)
pnpm db:push Push schema changes to database
pnpm db:studio Open Drizzle Studio
pnpm db:generate Generate migrations
pnpm db:migrate Run migrations

Project structure

my-app/
├── apps/
│   ├── admin/          # Next.js App Router — admin portal
│   ├── web/            # Next.js Pages Router — consumer web
│   ├── mobile/         # Expo — iOS + Android
│   ├── app/            # Vite — ticket/public app
│   └── server/         # Fastify — API + auth
├── packages/
│   ├── auth/           # Better Auth config (shared)
│   ├── db/             # Drizzle schema + migrations
│   ├── env/            # t3-env per app
│   ├── ui/             # shadcn/ui component library
│   └── config/         # Shared tsconfig
├── biome.json          # Linting + formatting (root)
├── turbo.json          # Turborepo pipeline
└── pnpm-workspace.yaml

Linting

Biome is configured at the root and covers all apps and packages. It replaces both ESLint and Prettier.

pnpm check          # fix safe issues
pnpm lint:fix       # fix everything including Tailwind class sorting

Tailwind class sorting uses Biome's useSortedClasses rule (nursery) — it won't auto-apply on save, only via lint:fix.


License

MIT

About

Because nobody wants to spend three days wiring up apps and services before writing a single line of real code! One command gets you a full Turborepo monorepo with auth, database, and multi-platform support using React, Next.js, Expo, Fastify all setup up and ready to go.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages