Roxabi Boilerplate

Configuration

Setup instructions and environment variables for Roxabi Boilerplate

Prerequisites

  • Bun >= 1.3
  • Node.js >= 24 (for compatibility)
  • Docker (for local PostgreSQL)
  • Git

Installation

# Clone the repository
git clone <repo-url>
cd roxabi_boilerplate

# Install dependencies
bun install

Environment Variables

Copy the example file and configure:

cp .env.example .env

Required Variables

VariableDescriptionExample
NODE_ENVEnvironment modedevelopment
DATABASE_URLPostgreSQL connection stringpostgresql://roxabi:roxabi@localhost:5432/roxabi
BETTER_AUTH_SECRETSecret for BetterAuthRandom 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:seed

Seed 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.

CommandDescriptionProduction
bun db:upStart PostgreSQL (Docker Compose)
bun db:downStop PostgreSQL (preserves data)
bun db:migrateApply pending Drizzle migrationsAllowed
bun db:generateGenerate migrations from schema changesAllowed
bun db:seedSeed dev data (user, org, RBAC)Blocked
bun db:resetTruncate 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:reset and db:seed refuse to run when NODE_ENV=production (enforced at both the bash dispatcher and TypeScript script level).

Optional Variables

VariableDescriptionDefault
APP_URLFrontend URLhttp://localhost:3000
API_URLBackend URLhttp://localhost:4000
GITHUB_TOKENGitHub API access-

Public Variables (exposed to client)

VariableDescriptionDefault
VITE_GITHUB_REPO_URLGitHub repository URL shown in UI-

Claude Code Agent Teams

VariableDescriptionDefault
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMSEnable multi-agent coordination (experimental)0
CLAUDE_CODE_TEAMMATE_MODEControls 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=1

Agent 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 .env files in app directories.

Core

VariableAppRequiredDefaultScopeDescription
NODE_ENVAPI, WebNodevelopmentServerEnvironment mode
PORTAPINo4000ServerAPI server port
WEB_PORTWebNo3000ServerWeb dev server port
EMAIL_PORTEmailNo3001ServerEmail preview server port
API_URLWebDev: No, Prod: Yeshttp://localhost:4000ServerBackend API URL
APP_URLAPI, WebNoServerFrontend URL
CORS_ORIGINAPINohttp://localhost:3000ServerAllowed CORS origin
LOG_LEVELAPINodebugServerLog verbosity

Database

VariableAppRequiredDefaultScopeDescription
DATABASE_URLAPIYes (prod)ServerPostgreSQL connection string
DATABASE_APP_URLAPINoServerApp user connection URL (RLS enforced — use this instead of DATABASE_URL for the API server)

Authentication

VariableAppRequiredDefaultScopeDescription
BETTER_AUTH_SECRETAPIYes (non-dev)dev-secret-...ServerAuth session secret
BETTER_AUTH_URLAPINohttp://localhost:4000ServerAuth base URL
GOOGLE_CLIENT_IDAPINoServerGoogle OAuth client ID
GOOGLE_CLIENT_SECRETAPINoServerGoogle OAuth client secret
GITHUB_CLIENT_IDAPINoServerGitHub OAuth client ID
GITHUB_CLIENT_SECRETAPINoServerGitHub OAuth client secret
RESEND_API_KEYAPINoServerResend email API key
EMAIL_FROMAPINonoreply@yourdomain.comServerSender email

Rate Limiting & API Features

VariableAppRequiredDefaultScopeDescription
KV_REST_API_URLAPIProd (if rate limit)ServerUpstash Redis URL
KV_REST_API_TOKENAPIProd (if rate limit)ServerUpstash Redis token
RATE_LIMIT_ENABLEDAPINotrueServerRate limiting toggle
SWAGGER_ENABLEDAPINoServerSwagger UI toggle
RATE_LIMIT_GLOBAL_TTLAPINo60000ServerGlobal window (ms)
RATE_LIMIT_GLOBAL_LIMITAPINo60ServerGlobal max requests
RATE_LIMIT_AUTH_TTLAPINo60000ServerAuth window (ms)
RATE_LIMIT_AUTH_LIMITAPINo5ServerAuth max requests
RATE_LIMIT_AUTH_BLOCK_DURATIONAPINo300000ServerAuth block (ms)
RATE_LIMIT_API_TTLAPINo60000ServerAPI key window (ms)
RATE_LIMIT_API_LIMITAPINo100ServerAPI key max requests

Scheduled Tasks

VariableAppRequiredDefaultScopeDescription
CRON_SECRETAPINoServerShared secret for authenticating cron job requests

Deployment

VariableAppRequiredDefaultScopeDescription
VERCEL_ENVAPI, WebNoServerAuto-injected by Vercel (production / preview / development)

Public (Client-Side)

VariableAppRequiredDefaultScopeDescription
VITE_GITHUB_REPO_URLWebNoClientGitHub URL in header

Tooling

VariableAppRequiredDefaultScopeDescription
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMSNo0LocalAgent teams toggle
GITHUB_TOKENNoLocal/CIGitHub 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 servers
  • build - Build all packages
  • codegen - Generate routes and i18n files
  • typecheck - Type checking
  • lint - Run linter
  • test - Run tests
  • clean - Remove build artifacts and caches
  • license: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:

VariableDescriptionExample
API_URLVercel API project URLhttps://api.roxabi.vercel.app
APP_URLThis project's URLhttps://app.roxabi.vercel.app

Vercel — API Project

Configure in Vercel dashboard under Settings > Environment Variables (manual vars) or via Marketplace Integrations (auto-injected vars):

VariableDescriptionSourceExample
DATABASE_URLPostgreSQL connection (Neon)Auto-injected by Neon Marketplace integrationpostgresql://user:pass@host/neondb?sslmode=require
DATABASE_APP_URLApp user connection URL (RLS enforced)Manualpostgresql://app_user:pass@host/neondb?sslmode=require
CORS_ORIGINWeb project URLManualhttps://app.roxabi.vercel.app
BETTER_AUTH_SECRETAuth secret (random 32+ chars)Manual&lt;random-string&gt;
BETTER_AUTH_URLThis project's URLManualhttps://api.roxabi.vercel.app
APP_URLWeb project URLManualhttps://app.roxabi.vercel.app
API_URLThis project's URLManualhttps://api.roxabi.vercel.app
EMAIL_FROMSender email addressManualnoreply@example.com
RESEND_API_KEYResend API key for transactional emailsAuto-injected by Resend Marketplace integrationre_...
KV_REST_API_URLUpstash Redis REST URLAuto-injected by Upstash Marketplace integrationhttps://...upstash.io
KV_REST_API_TOKENUpstash Redis REST tokenAuto-injected by Upstash Marketplace integrationAX...
RATE_LIMIT_ENABLEDEnable/disable rate limiting (kill switch)Manualtrue
SWAGGER_ENABLEDEnable Swagger UI at /api/docsManualfalse
RATE_LIMIT_GLOBAL_TTLGlobal rate limit window in msManual60000
RATE_LIMIT_GLOBAL_LIMITGlobal max requests per windowManual60
RATE_LIMIT_AUTH_TTLAuth rate limit window in msManual60000
RATE_LIMIT_AUTH_LIMITAuth max requests per windowManual5
RATE_LIMIT_AUTH_BLOCK_DURATIONAuth tier block duration in msManual300000
RATE_LIMIT_API_TTLAPI key tier rate limit window in ms (reserved for future use)Manual60000
RATE_LIMIT_API_LIMITAPI key tier max requests per window (reserved for future use)Manual100

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.

We use cookies to improve your experience. You can accept all, reject all, or customize your preferences.