🌐 Language: English · Tiếng Việt · 中文 · 한국어
Get the full boilerplate running locally in 15 minutes.
| Tool | Version | Install |
|---|---|---|
| Node | 20+ | nvm install 20 |
| pnpm | 9+ | npm install -g pnpm@9 |
| FVM | latest | dart pub global activate fvm |
| Flutter | 3.27+ | fvm install 3.27.0 |
| Java | 17+ | java -version (for codegen) |
| Docker | (optional) | For Postgres + API image |
Verify:
node --version # v20.x.x
pnpm --version # 9.x.x
fvm --version # latest
dart --version # 3.5.x
java -version # openjdk 17+Add ~/.pub-cache/bin to PATH so melos (and other Dart pub global tools) resolve after activation:
# bash / zsh
echo 'export PATH="$PATH:$HOME/.pub-cache/bin"' >> ~/.profile
source ~/.profile
# fish
fish_add_path ~/.pub-cache/bin# 1. Clone repo
git clone https://github.com/yourorg/mobile-boilerplate.git
cd mobile-boilerplate
# 2a. Backend-only dev (no Flutter / Java needed)
pnpm bootstrap
# 2b. Full stack (mobile + codegen) — requires FVM + Java 17 on PATH
pnpm bootstrap:fullWhat each script does:
| Script | Steps | When to use |
|---|---|---|
pnpm bootstrap |
pnpm install |
Backend-only contributors |
pnpm bootstrap:full |
pnpm install → pnpm install:melos → pnpm codegen:api → melos bootstrap |
Mobile dev / full validation |
Why split?
melosis a Dart pub package, not on npm — it's activated lazily viafvm dart pub global activate melos. The codegen step needs Java 17 (openapi-generator-cli) and Flutter SDK (build_runner). Backend-only contributors skip those prereqs.
Start Postgres:
docker-compose up -d postgres
# Container runs on localhost:5432, user=postgres, password=postgresCreate .env:
cp apps/api/.env.example apps/api/.envEdit .env:
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/boilerplate"
DIRECT_URL="postgresql://postgres:postgres@localhost:5432/boilerplate"
SKIP_DB=false
NODE_ENV=development
LOG_LEVEL=debug
API_PORT=3000New env vars (Phase 02 hardening):
| Var | Default | Description |
|---|---|---|
TRUST_PROXY |
0 |
Number of proxy hops in front. Set to 1 if behind LB/Cloudflare. |
BODY_LIMIT |
1mb |
Max JSON/urlencoded body size. Use multer for file uploads. |
Run migrations:
pnpm --filter @mobile-boilerplate/api prisma:migrate dev- Create project at https://supabase.com
- Copy DATABASE_URL + DIRECT_URL from "Connection Pooler"
- Paste into
.env - Run migrations:
pnpm --filter @mobile-boilerplate/api prisma:migrate deploy
To run API without a database (hello endpoint only):
# .env
SKIP_DB=true
DIRECT_URL="postgresql://unused@unused:5432/unused" # Not usedpnpm --filter @mobile-boilerplate/api devOutput:
[Nest] 12345 - 04/27/2026, 10:00:00 AM LOG [NestFactory] Starting Nest application...
[Nest] 12345 - 04/27/2026, 10:00:01 AM LOG [InstanceLoader] TypeOrmModule dependencies initialized +123ms
[Nest] 12345 - 04/27/2026, 10:00:02 AM LOG [NestApplication] Nest application successfully started +456ms
Verify:
curl http://localhost:3000/health
# {"data":{"status":"ok"},"meta":{...},"error":null}
curl http://localhost:3000/hello
# {"data":{"message":"Hello World","timestamp":"..."},"meta":{...},"error":null}Swagger: http://localhost:3000/api-docs (development mode only; set ENABLE_SWAGGER=true for non-dev)
cp apps/mobile/.env.example apps/mobile/.envDefault .env:
FLAVOR=dev
API_BASE_URL=auto
LOG_LEVEL=debugAPI_BASE_URL resolution:
| Platform | Value | Resolves To |
|---|---|---|
| Android emulator | auto |
http://10.0.2.2:3000 |
| iOS simulator | auto |
http://localhost:3000 |
| Web (localhost) | auto |
http://localhost:3000 |
| Real device | explicit IP | http://192.168.1.42:3000 |
For real device on local network:
# Find your machine's IP
ifconfig | grep "inet 192" # macOS/Linux
ipconfig | grep IPv4 # Windows
# Edit .env
API_BASE_URL=http://192.168.1.42:3000cd apps/mobile
fvm flutter run --dart-define=FLAVOR=devFirst run (2–3 min):
- Builds APK
- Installs on emulator/device
- Launches app
Output (success):
Launching lib/main.dart on Android Emulator in debug mode...
✓ Built build/app/outputs/apk/debug/app-debug.apk
Installing and launching...
D/HostConnection( xxxx): hostConnection obtained, fd=44
I/System (xxxx): [MAIN] app launched successfully
- Tap "Fetch Hello" button
- UI shows: "Hello World" + timestamp
- Check logs:
adb logcat | grep "DEBUG"to see Dio requests
Error: "EADDRINUSE: address already in use :::3000"
# Find process using 3000
lsof -i :3000
# Kill it
kill -9 <PID>
# Or use different port
API_PORT=3001 pnpm devError: "connect ECONNREFUSED 127.0.0.1:5432"
# Postgres not running
docker-compose up -d postgres
# Or set SKIP_DB=trueError: "Could not resolve package:api_client"
# Regenerate client
pnpm codegen:api
# Reinstall
cd apps/mobile && fvm flutter pub getError: "Android SDK version X too low"
# Update SDK via Android Studio
# Settings → SDK Manager → SDK Platforms → Android 34Error: "Certificate verification failed"
# Proxy/corporate network issue
cd apps/mobile
fvm flutter config --no-analytics
fvm flutter run --verbose # See full errorError: "Connection refused" on mobile
- Check backend running:
curl http://localhost:3000/hello - Verify .env
API_BASE_URL=auto(or explicit IP) - Android emulator only: use
10.0.2.2, notlocalhost
Error: "Invalid response envelope" or "type mismatch"
- API client may be stale:
pnpm codegen:api - Check Swagger at http://localhost:3000/api-docs
- Verify
@ApiStandardResponse(Dto)on controller
# Backend-only install
pnpm bootstrap
# Full stack (pnpm + activate melos + codegen + melos bootstrap)
pnpm bootstrap:full
# Lint & test (all)
pnpm lint
pnpm test
# Backend only
pnpm --filter @mobile-boilerplate/api dev # Start
pnpm --filter @mobile-boilerplate/api test # Test
pnpm --filter @mobile-boilerplate/api lint # Lint
# Mobile only
cd apps/mobile
fvm flutter pub get # Install
fvm flutter analyze # Lint
fvm flutter test # Test
fvm flutter run --flavor=dev # Run
# Regenerate API client
pnpm codegen:api
# View Swagger UI (also OpenAPI JSON at /api-docs/json)
# http://localhost:3000/api-docs (dev only; ENABLE_SWAGGER=true for non-dev)
# Stop all
docker-compose down # Stop Postgres
^C in terminal # Stop backend + frontend- Add Backend Module — create API endpoint
- Add Flutter Feature — build mobile screen
- Code Standards — conventions to follow
- Project Overview — understand scope
Still stuck? Check logs:
# Backend logs
pnpm --filter @mobile-boilerplate/api dev 2>&1 | tee backend.log
# Mobile logs
adb logcat | grep flutter
# API client generation
pnpm codegen:api --verbose