Generate a full-stack monorepo in one command.
Next.js · Expo · Wails · tRPC · Better Auth · Prisma · Turbo
English · မြန်မာ
Ranger is a zero-dependency Node.js CLI that scaffolds production-ready monorepos for full-stack apps with web, mobile, auth, API, and database already wired together.
It is the official project generator for the Dahlai-style stack — real source files you own, not a black-box framework.
npm: create-ranger
Ranger is a project generator (CLI), not a library you add to
dependencies.
The npm sidebar shows npm i create-ranger — that only installs the CLI tool. To generate a new project, use one of these:
# ✅ recommended — run once, no install
npx create-ranger my-app
# ✅ npm create shorthand (same package)
npm create ranger my-app
# ✅ after global install
npm install -g create-ranger
ranger my-app| ✅ Generate a project | ❌ Wrong |
|---|---|
npx create-ranger my-app |
npm i create-ranger alone (installs CLI only, creates nothing) |
npm create ranger my-app |
Adding create-ranger to your app's package.json |
pnpm dlx create-ranger my-app |
Expecting a library import like import {} from "create-ranger" |
From an empty folder, run Ranger, set up the database, and start dev:
# 1. Generate a new project (interactive prompts)
npx create-ranger my-app
# 2. Install dependencies
cd my-app
pnpm install
# 3. Set secrets, create the database, then seed
# - BETTER_AUTH_SECRET in .env
# - SEED_ADMIN_PASSWORD in packages/db/.env
pnpm db:reset # type "yes" when prompted
pnpm db:push
pnpm db:seed
# 4. Start all apps
pnpm devOpen http://localhost:3000, then sign up at /login or use the admin account created by pnpm db:seed in your generated project.
One-liner (non-interactive, full stack + Express API + desktop):
npx create-ranger my-app --yes --web --mobile --desktop --backend expressStarting a full-stack monorepo usually means repeating the same work:
- wiring auth across web and mobile
- sharing API types between clients and server
- choosing a backend shape (Next.js routes vs Express)
- setting up Prisma, seed data, admin roles, and env files in the right places
- documenting architecture conventions for your team and AI tools
Ranger generates that foundation in one command so you can focus on product logic instead of boilerplate.
Every generated project includes:
| Layer | Technology |
|---|---|
| Workspace | pnpm workspaces + Turbo |
| API | Shared @repo/api package with tRPC routers |
| Auth | Better Auth with Prisma adapter, admin plugin, Expo support |
| Database | Prisma + PostgreSQL (Better Auth models + Post model) |
| Web (optional) | Next.js 15 App Router, shadcn-style black & white UI |
| Mobile (optional) | Expo Router, React Native StyleSheet only |
| Desktop (optional) | Wails v2 app reusing the Next.js web UI via Vite |
| Backend | Next.js API routes or Express server |
| Tooling | Shared TypeScript config, Prettier, Cursor rules |
- Email/password auth with role-based access (
user,admin, etc.) - Public post feed + authenticated post creation with image upload
- Admin dashboard: users, posts, summary stats
- Database seed script for local admin user and sample post
.cursor/rulesfor API, database, web, and mobile architecture
| Tool | Version |
|---|---|
| Node.js | >= 20 |
| pnpm | 9.x (generated apps pin pnpm@9.12.0) |
| PostgreSQL | local instance with psql available |
| Expo Go / simulator | only if you enable the mobile app |
| Go + Wails CLI v2 | only if you enable the desktop app (go 1.23+) |
Package name on npm: create-ranger
You do not need to clone this repo. Pick one method below.
Run the latest version without installing anything globally:
npx create-ranger my-appPin a version:
npx create-ranger@1.0.7 my-appnpm create ranger my-appThis runs the create-ranger package (npm strips the create- prefix).
pnpm dlx create-ranger my-appyarn create ranger my-appOnly if you want the ranger command available everywhere:
npm install -g create-ranger
ranger my-app # primary
create-ranger my-app # same CLI
renger my-app # typo-safe alias
npm i create-ranger(without-g) installs the CLI into the current project'snode_modules. That is rarely what you want — prefernpx create-rangerinstead.
git clone https://github.com/rangorithm/ranger.git
cd ranger
node ./bin/ranger.js my-app| Goal | Command |
|---|---|
| Generate project (best) | npx create-ranger <name> |
| Generate via npm create | npm create ranger <name> |
| Generate via pnpm | pnpm dlx create-ranger <name> |
| Generate via yarn | yarn create ranger <name> |
| Use global CLI | ranger <name> after npm i -g create-ranger |
npx create-ranger my-app
# creates → ./my-app/Ranger only writes inside the target folder.
Run Ranger without flags to walk through setup:
npx create-rangerYou will be asked:
- Project name — becomes the folder name and
package.jsonname (kebab-case) - Include Expo mobile app? —
Y/n - Include Next.js web/admin app? —
Y/n - Include Wails desktop app? —
y/N - Backend server — choose one (defaults to Express when desktop is enabled):
Next.js API routes + tRPCExpress server + tRPC
Ranger writes the project into ./<project-name> relative to your current directory.
ranger <project-name> [options]| Flag | Description |
|---|---|
--yes, -y |
Skip prompts; use defaults |
--force, -f |
Overwrite generated files in a non-empty target directory |
--web |
Include the Next.js web/admin app |
--no-web |
Exclude the web app (Express backend only) |
--mobile |
Include the Expo mobile app |
--no-mobile |
Exclude the mobile app |
--desktop |
Include the Wails desktop app |
--no-desktop |
Exclude the desktop app |
--backend next |
Use Next.js API routes for auth, tRPC, and uploads |
--backend express |
Use a standalone Express server on port 4000 |
--backend=express |
Same as --backend express |
Full stack with Express backend (recommended for web + mobile + desktop):
npx create-ranger my-app --yes --web --mobile --desktop --backend expressWeb + desktop with Express API:
npx create-ranger my-app --yes --web --no-mobile --desktop --backend expressWeb-only with Next.js API routes:
npx create-ranger my-app --yes --web --no-mobile --backend nextMobile-only with Express API:
npx create-ranger my-app --yes --no-web --mobile --backend expressCI / automation with forced overwrite:
npx create-ranger my-app --yes --web --mobile --backend express --force| Setting | Default |
|---|---|
| Project name | my-ranger-app (if not provided) |
| Web app | enabled |
| Mobile app | enabled |
| Desktop app | disabled |
| Backend | next (or express when --desktop is passed) |
Note: Choosing
--backend nextalways enables the web app, because Next.js hosts the API routes.
Note: The desktop app requires the web app and an Express backend. It reuses
apps/webthrough Vite aliases and calls the API viaVITE_API_URL.
Ranger supports two backend architectures. Pick the one that matches how you want to deploy.
Browser / Mobile → Next.js (port 3000)
├── /api/auth/*
├── /api/trpc/*
└── /api/uploads
- Single origin for web and API
NEXT_PUBLIC_API_URLis empty — clients use same-origin requests- Best for: web-first apps, Vercel-style deployments, simpler local dev
Web (3000) ──→ Express API (4000)
Mobile ──→ ├── /api/auth/*
├── /api/trpc/*
└── /api/uploads
- Web and API run as separate processes
NEXT_PUBLIC_API_URL=http://localhost:4000inapps/web/.env- Best for: mobile + web combos, custom server middleware, traditional API deployment
| Next backend | Express backend | |
|---|---|---|
| API port | 3000 (shared with web) |
4000 |
| Web env | same-origin | points to :4000 |
apps/server/ |
not generated | generated |
| Mobile API URL | http://localhost:3000 |
http://localhost:4000 |
my-app/
├── apps/
│ ├── web/ # Next.js admin + public app (if enabled)
│ ├── mobile/ # Expo app (if enabled)
│ ├── desktop/ # Wails desktop app (if enabled)
│ └── server/ # Express API (express backend only)
├── packages/
│ ├── api/ # tRPC routers: post, user, admin
│ ├── auth/ # Better Auth config + session helpers
│ └── db/ # Prisma schema, client, seed script
├── tooling/
│ └── typescript-config/ # shared tsconfig presets
├── scripts/
│ └── reset-database.sh # creates local Postgres DB from project name
├── .cursor/rules/ # architecture rules for Cursor AI
├── .env # root env (reference)
├── turbo.json
├── pnpm-workspace.yaml
└── package.json
Ranger derives names from your project folder:
| Input folder | package.json name |
Database name |
|---|---|---|
MyApp |
my-app |
my_app |
TestRanger |
test-ranger |
test_ranger |
The database name is the kebab-case package name converted to snake_case.
See Quick start for the full copy-paste flow. This section explains each step in detail.
After Ranger creates your project:
cd my-app
pnpm installOpen .env and set a real auth secret:
BETTER_AUTH_SECRET="use-a-long-random-string-at-least-32-chars"Ranger also writes scoped env files where each runtime needs them:
| File | Used by |
|---|---|
packages/db/.env |
Prisma CLI |
apps/web/.env |
Next.js |
apps/server/.env |
Express (express backend only) |
apps/mobile/.env |
Expo |
apps/desktop/frontend/.env |
Wails desktop (VITE_API_URL) |
pnpm db:resetType yes when prompted. This script:
- reads your
package.jsonname - creates a matching PostgreSQL database (e.g.
my_app) - updates
DATABASE_URLacross all env files - links
packages/db/.envto the root.env
pnpm db:push
pnpm db:seedpnpm dev| Script | What it does |
|---|---|
pnpm dev |
Turbo TUI — all selected apps |
pnpm dev:stream |
Same apps, plain log output |
pnpm dev:web |
Web/admin only |
pnpm dev:mobile |
Expo only |
pnpm dev:server |
Express API only |
pnpm desktop:setup |
Check/install Go and Wails CLI for desktop |
pnpm dev:desktop |
Wails desktop only |
pnpm dev:desktop:all |
Express API + Wails desktop |
After pnpm db:seed, open /login in the web app. You can sign in with the seeded admin user or create a new account via sign-up.
Update or remove the seed credentials in packages/db/prisma/seed.mjs before shipping to production.
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/my_app?schema=public"
BETTER_AUTH_SECRET="replace-with-a-long-random-secret"
BETTER_AUTH_URL="http://localhost:4000" # or :3000 for next backend
CORS_ORIGIN="http://localhost:3000"
NEXT_PUBLIC_API_URL="http://localhost:4000" # empty for next backend
EXPO_PUBLIC_API_URL="http://127.0.0.1:4000"
EXPO_PUBLIC_API_PORT="4000"| Service | URL |
|---|---|
| Web | http://localhost:3000 |
| API | http://localhost:4000 |
| Service | URL |
|---|---|
| Web + API | http://localhost:3000 |
Update apps/mobile/.env with your machine's LAN IP:
EXPO_PUBLIC_API_URL="http://192.168.1.10:4000"Android emulators auto-fallback to 10.0.2.2 in the generated mobile code.
Ranger encodes opinionated structure so teams (and AI assistants) stay consistent.
src/
├── app/ # thin route files only
├── modules/
│ ├── posts/ # public feature
│ ├── auth/ # login/signup
│ └── admin/ # admin-only features
├── components/ui/ # shared primitives
└── trpc/ # client setup
app/ # Expo Router screens (thin)
src/features/ # MVVM-style feature modules
└── posts/
├── components/
└── hooks/ # tRPC calls, navigation, uploads
frontend/src/ # Vite shell, auth storage, Next.js shims
apps/web/src/ # reused UI modules via Vite aliases
- Wails v2 wraps a Vite + React Router frontend
- Reuses web modules from
apps/web/src(posts, auth, admin) - Persists Better Auth session data through Go bindings
- Talks to the Express API at
VITE_API_URL(defaulthttp://localhost:4000)
Run pnpm desktop:setup to check for Go/Wails and install them when possible (also runs automatically right after project generation when desktop is enabled).
Local desktop dev:
pnpm dev:desktop:all # API + desktop window
# or separately:
pnpm dev:server
pnpm dev:desktopBuild a distributable app:
pnpm --filter @repo/desktop buildpublicProcedure— no auth requiredprotectedProcedure— signed-in user requiredadminProcedure— staff/admin role required
Routers: post, user, admin
Prisma models:
User,Session,Account,Verification— Better AuthPost— title, content, image, published flag, author relation
Every project ships .cursor/rules/:
| Rule file | Covers |
|---|---|
api/api.mdc |
tRPC procedure auth levels, Zod validation, error handling |
database/database-rule.mdc |
Prisma schema conventions |
web-arch/web-arch.mdc |
Next.js module layout |
mobile-arch/mobile-arch.mdc |
Expo MVVM + StyleSheet-only UI |
These rules are loaded automatically in Cursor to keep generated code aligned with the scaffold's architecture.
| Command | Description |
|---|---|
pnpm db:reset |
Drop & recreate local Postgres DB from project name |
pnpm db:push |
Push Prisma schema without migrations |
pnpm db:migrate |
Create & apply Prisma migrations |
pnpm db:seed |
Seed admin user + welcome post |
pnpm db:studio |
Open Prisma Studio |
pnpm db:generate |
Regenerate Prisma Client |
Prisma runs from packages/db/. Make sure packages/db/.env exists.
Fix:
pnpm db:reset # recreates DB and links env files
# or manually:
ln -sf ../../.env packages/db/.envThe web app is calling Next.js instead of the API server. Check apps/web/.env:
NEXT_PUBLIC_API_URL="http://localhost:4000"Then restart:
pnpm devAlso confirm the Express server is running — you should see:
API server running on http://localhost:4000
Ranger refuses to write into populated folders unless you pass --force:
npx create-ranger my-app --yes --web --mobile --backend express --forceInstall PostgreSQL client tools. On macOS with Homebrew:
brew install postgresql@17- iOS Simulator: use
http://127.0.0.1:4000orhttp://localhost:4000 - Android Emulator: code auto-uses
10.0.2.2 - Physical device: use your Mac's LAN IP in
apps/mobile/.env
Ranger is a single file: bin/ranger.js.
- Parse CLI args — project name, flags, backend choice
- Prompt (unless
--yes) — interactive configuration - Normalize — derive
packageName,dbName, ports, enabled apps - Generate — build a
filesmap with inline template strings for web, mobile, desktop, packages, and server - Write — create the directory tree on disk (text + embedded binary assets for Wails icons/fonts)
- Print next steps — install, db setup, dev commands
There are no runtime dependencies. The generated app dependencies are installed separately via pnpm install inside the new project.
The Wails desktop app lives in addDesktopApp() inside bin/ranger.js, same pattern as addWebApp() and addMobileApp(). When window-test/apps/desktop changes, regenerate the embed:
pnpm run generate:desktop-apppnpm run smokeGenerates a test project at /private/tmp/ranger-smoke with web, mobile, desktop, and Express backend.
- Not a framework — it generates a starting repo you fully own and modify
- Not a deployment tool — no Vercel/Fly/Railway config is generated
- Not a design system package — web UI uses lightweight shadcn-style primitives, not a published component library
- Not migration-aware by default —
db:pushis the default; usedb:migratewhen you need versioned migrations
- Additional backend targets (Hono, Fastify)
- Optional OAuth providers in the auth scaffold
- Docker Compose for local Postgres
- Template variants (e-commerce, SaaS dashboard, etc.)
Contributions and feature requests are welcome.
MIT — see LICENSE in the repository.
Built by Rangorithm
Generate once. Ship features.
