Configuration
Setup instructions and environment variables for Roxabi Boilerplate
Prerequisites
Installation
# Clone the repository
git clone <repo-url>
cd roxabi_boilerplate
# Install dependencies
bun installEnvironment Variables
Copy the example file and configure:
cp .env.example .envRequired Variables
| Variable | Description | Example |
|---|---|---|
NODE_ENV | Environment mode | development |
DATABASE_URL | PostgreSQL connection string | postgresql://roxabi:roxabi@localhost:5432/roxabi |
BETTER_AUTH_SECRET | Secret for BetterAuth | Random 32+ character string |
Branch Databases (Local Development)
Each git worktree gets its own isolated PostgreSQL database named roxabi_<issue_number> within the shared Docker container. This prevents schema conflicts when multiple worktrees run concurrent migrations.
Branch databases are created automatically by /implement during worktree setup, or manually:
cd apps/api
# Create a branch database (migrate + seed + update .env)
bun run db:branch:create
# Create with explicit issue number (non-interactive)
bun run db:branch:create --force 150
# Drop a branch database
bun run db:branch:drop
# List all branch databases and their worktree status
bun run db:branch:list
# Seed a fresh database with dev essentials
bun run db:seedSeed credentials: dev@roxabi.local / password123 (1 user, 1 organization, RBAC roles seeded).
All scripts run from apps/api/ and use docker exec against the roxabi-postgres container. No local psql installation is required.
Database Scripts (Root-Level)
Root-level wrappers load .env automatically and delegate to apps/api/. No need to cd into apps/api or set DATABASE_URL manually.
| Command | Description | Production |
|---|---|---|
bun db:up | Start PostgreSQL (Docker Compose) | — |
bun db:down | Stop PostgreSQL (preserves data) | — |
bun db:migrate | Apply pending Drizzle migrations | Allowed |
bun db:generate | Generate migrations from schema changes | Allowed |
bun db:seed | Seed dev data (user, org, RBAC) | Blocked |
bun db:reset | Truncate all tables (CASCADE) | Blocked |
Common workflow:
# Fresh start after cloning
bun db:up && bun db:migrate && bun db:seed
# Reset and re-seed during development
bun db:reset && bun db:seed
db:resetanddb:seedrefuse to run whenNODE_ENV=production(enforced at both the bash dispatcher and TypeScript script level).
Optional Variables
| Variable | Description | Default |
|---|---|---|
APP_URL | Frontend URL | http://localhost:3000 |
API_URL | Backend URL | http://localhost:4000 |
GITHUB_TOKEN | GitHub API access | - |
Public Variables (exposed to client)
| Variable | Description | Default |
|---|---|---|
VITE_GITHUB_REPO_URL | GitHub repository URL shown in UI | - |
Claude Code Agent Teams
| Variable | Description | Default |
|---|---|---|
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS | Enable multi-agent coordination (experimental) | 0 |
CLAUDE_CODE_TEAMMATE_MODE | Controls teammate display: in-process (same terminal) or split-pane (separate panes) | in-process |
To enable agent teams, set in your shell:
export CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1Agent definitions are in .claude/agents/*.md. See the Agent Teams Guide for details.
Complete Environment Variable Reference
Environment files (
.env,.env.local) are resolved from the monorepo root only. Do not place.envfiles in app directories.
Core
| Variable | App | Required | Default | Scope | Description |
|---|---|---|---|---|---|
NODE_ENV | API, Web | No | development | Server | Environment mode |
PORT | API | No | 4000 | Server | API server port |
WEB_PORT | Web | No | 3000 | Server | Web dev server port |
EMAIL_PORT | No | 3001 | Server | Email preview server port | |
API_URL | Web | Dev: No, Prod: Yes | http://localhost:4000 | Server | Backend API URL |
APP_URL | API, Web | No | — | Server | Frontend URL |
CORS_ORIGIN | API | No | http://localhost:3000 | Server | Allowed CORS origin |
LOG_LEVEL | API | No | debug | Server | Log verbosity |
Database
| Variable | App | Required | Default | Scope | Description |
|---|---|---|---|---|---|
DATABASE_URL | API | Yes (prod) | — | Server | PostgreSQL connection string |
DATABASE_APP_URL | API | No | — | Server | App user connection URL (RLS enforced — use this instead of DATABASE_URL for the API server) |
Authentication
| Variable | App | Required | Default | Scope | Description |
|---|---|---|---|---|---|
BETTER_AUTH_SECRET | API | Yes (non-dev) | dev-secret-... | Server | Auth session secret |
BETTER_AUTH_URL | API | No | http://localhost:4000 | Server | Auth base URL |
GOOGLE_CLIENT_ID | API | No | — | Server | Google OAuth client ID |
GOOGLE_CLIENT_SECRET | API | No | — | Server | Google OAuth client secret |
GITHUB_CLIENT_ID | API | No | — | Server | GitHub OAuth client ID |
GITHUB_CLIENT_SECRET | API | No | — | Server | GitHub OAuth client secret |
RESEND_API_KEY | API | No | — | Server | Resend email API key |
EMAIL_FROM | API | No | noreply@yourdomain.com | Server | Sender email |
Rate Limiting & API Features
| Variable | App | Required | Default | Scope | Description |
|---|---|---|---|---|---|
KV_REST_API_URL | API | Prod (if rate limit) | — | Server | Upstash Redis URL |
KV_REST_API_TOKEN | API | Prod (if rate limit) | — | Server | Upstash Redis token |
RATE_LIMIT_ENABLED | API | No | true | Server | Rate limiting toggle |
SWAGGER_ENABLED | API | No | — | Server | Swagger UI toggle |
RATE_LIMIT_GLOBAL_TTL | API | No | 60000 | Server | Global window (ms) |
RATE_LIMIT_GLOBAL_LIMIT | API | No | 60 | Server | Global max requests |
RATE_LIMIT_AUTH_TTL | API | No | 60000 | Server | Auth window (ms) |
RATE_LIMIT_AUTH_LIMIT | API | No | 5 | Server | Auth max requests |
RATE_LIMIT_AUTH_BLOCK_DURATION | API | No | 300000 | Server | Auth block (ms) |
RATE_LIMIT_API_TTL | API | No | 60000 | Server | API key window (ms) |
RATE_LIMIT_API_LIMIT | API | No | 100 | Server | API key max requests |
Scheduled Tasks
| Variable | App | Required | Default | Scope | Description |
|---|---|---|---|---|---|
CRON_SECRET | API | No | — | Server | Shared secret for authenticating cron job requests |
Deployment
| Variable | App | Required | Default | Scope | Description |
|---|---|---|---|---|---|
VERCEL_ENV | API, Web | No | — | Server | Auto-injected by Vercel (production / preview / development) |
Public (Client-Side)
| Variable | App | Required | Default | Scope | Description |
|---|---|---|---|---|---|
VITE_GITHUB_REPO_URL | Web | No | — | Client | GitHub URL in header |
Tooling
| Variable | App | Required | Default | Scope | Description |
|---|---|---|---|---|---|
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS | — | No | 0 | Local | Agent teams toggle |
GITHUB_TOKEN | — | No | — | Local/CI | GitHub API access |
TypeScript Configuration
Root tsconfig.json provides base settings. Each app/package extends it:
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist"
}
}Biome Configuration
Linting and formatting configured in biome.json:
- 2-space indentation
- Single quotes
- No semicolons (ASI)
- 100 character line width
TurboRepo Configuration
Tasks defined in turbo.jsonc:
dev- Run development serversbuild- Build all packagescodegen- Generate routes and i18n filestypecheck- Type checkinglint- Run lintertest- Run testsclean- Remove build artifacts and cacheslicense:check- Scan dependency licenses for compliance
Environment Variables in Turbo
The root turbo.jsonc declares env arrays for variables that affect build output — changing these values invalidates the Turbo cache:
codegen:API_URL,APP_URL,VITE_*build:API_URL,APP_URL,KV_*,REDIS_*,VITE_*test:CI,VITEST
Wildcard patterns (e.g. VITE_*) automatically match all env vars with that prefix — no manual update to turbo.jsonc needed when adding new vars with a known prefix. For new prefixes, add a wildcard pattern to the relevant task.
The API app extends the root config via apps/api/turbo.json with passThroughEnv for runtime secrets (database, auth). These are available at runtime but don't affect the build cache, preventing unnecessary rebuilds when only secrets change.
IDE Setup
VS Code
Recommended extensions:
- Biome
- TypeScript
- Turbo Console Log
Settings:
{
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true
}Production Environment
Production runs entirely on Vercel with two projects (web + API). Environment variables are configured in each project's dashboard.
Vercel — Web Project
Configure in Vercel dashboard under Settings > Environment Variables:
| Variable | Description | Example |
|---|---|---|
API_URL | Vercel API project URL | https://api.roxabi.vercel.app |
APP_URL | This project's URL | https://app.roxabi.vercel.app |
Vercel — API Project
Configure in Vercel dashboard under Settings > Environment Variables (manual vars) or via Marketplace Integrations (auto-injected vars):
| Variable | Description | Source | Example |
|---|---|---|---|
DATABASE_URL | PostgreSQL connection (Neon) | Auto-injected by Neon Marketplace integration | postgresql://user:pass@host/neondb?sslmode=require |
DATABASE_APP_URL | App user connection URL (RLS enforced) | Manual | postgresql://app_user:pass@host/neondb?sslmode=require |
CORS_ORIGIN | Web project URL | Manual | https://app.roxabi.vercel.app |
BETTER_AUTH_SECRET | Auth secret (random 32+ chars) | Manual | <random-string> |
BETTER_AUTH_URL | This project's URL | Manual | https://api.roxabi.vercel.app |
APP_URL | Web project URL | Manual | https://app.roxabi.vercel.app |
API_URL | This project's URL | Manual | https://api.roxabi.vercel.app |
EMAIL_FROM | Sender email address | Manual | noreply@example.com |
RESEND_API_KEY | Resend API key for transactional emails | Auto-injected by Resend Marketplace integration | re_... |
KV_REST_API_URL | Upstash Redis REST URL | Auto-injected by Upstash Marketplace integration | https://...upstash.io |
KV_REST_API_TOKEN | Upstash Redis REST token | Auto-injected by Upstash Marketplace integration | AX... |
RATE_LIMIT_ENABLED | Enable/disable rate limiting (kill switch) | Manual | true |
SWAGGER_ENABLED | Enable Swagger UI at /api/docs | Manual | false |
RATE_LIMIT_GLOBAL_TTL | Global rate limit window in ms | Manual | 60000 |
RATE_LIMIT_GLOBAL_LIMIT | Global max requests per window | Manual | 60 |
RATE_LIMIT_AUTH_TTL | Auth rate limit window in ms | Manual | 60000 |
RATE_LIMIT_AUTH_LIMIT | Auth max requests per window | Manual | 5 |
RATE_LIMIT_AUTH_BLOCK_DURATION | Auth tier block duration in ms | Manual | 300000 |
RATE_LIMIT_API_TTL | API key tier rate limit window in ms (reserved for future use) | Manual | 60000 |
RATE_LIMIT_API_LIMIT | API key tier max requests per window (reserved for future use) | Manual | 100 |
Auto-injected vars are managed by their respective Vercel Marketplace integrations and do not need manual configuration. They appear with an integration badge in the Vercel dashboard. For local development, these vars still need to be set manually in
.env.
Note: Vercel auto-sets
NODE_ENV=production. NestJS runs as a Vercel Function with Fluid compute.
See the Deployment Guide for full setup instructions.