┌─────────────────────────────────────────────────────────────┐
│ User Opens http://localhost:3000 │
│ Sees Stack Builder UI with Technology Options │
│ │
│ Selects: │
│ - Framework: Next.js ✓ │
│ - Database: MongoDB (optional) │
│ - Auth: Auth.js (optional) │
│ - Clicks "Generate & Download" │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Frontend (app/page.tsx) │
│ - Collects user selections into StackBlueprint │
│ - Makes POST to /api/generate │
│ - Receives tar.gz file │
│ - Triggers browser download │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ API Route (app/api/generate/route.ts) │
│ - Receives POST request with StackBlueprint JSON │
│ - Calls generateProject(blueprint) │
│ - Returns tar.gz buffer with Content-Type: application/gzip │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Generation Pipeline (packages/engine/generate.ts) │
│ Creates temp directory at: /tmp/BaseCompose-XXXXX/project │
│ │
│ Step 1: Copy Framework Base │
│ ────────────────────────────────────────────────────────────│
│ packages/engine/copy.ts::copyFrameworkBase() │
│ - Copies templates/frameworks/nextjs/base/* → /tmp/.../ │
│ - Copies templates/frameworks/nextjs/docker/* → /tmp/.../ │
│ │
│ Project now has: │
│ ├── app/ │
│ ├── public/ │
│ ├── package.json (with mongodb, next-auth deps) │
│ ├── Dockerfile │
│ └── .dockerignore │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Step 2: Apply Addons │
│ ────────────────────────────────────────────────────────────│
│ packages/engine/copy.ts::copyAddonFiles() │
│ │
│ For each selected addon: │
│ │
│ IF database == "mongodb": │
│ - Copy templates/databases/mongodb/client.ts │
│ → app/lib/db/mongodb.ts │
│ - Addon state updated: selectedAddons += "mongodb" │
│ │
│ IF auth == "authjs": │
│ - Copy templates/auth/authjs/config.ts │
│ → app/lib/auth/config.ts │
│ - Copy templates/auth/authjs/routes/[...nextauth].ts │
│ → app/api/auth/[...nextauth].ts │
│ - Addon state updated: selectedAddons += "authjs" │
│ │
│ ALWAYS (demo): │
│ - Copy templates/demo/ui/page.tsx │
│ → app/lib/components/demo-hero.tsx │
│ - Copy templates/demo/api/health.ts │
│ → app/api/health.ts │
│ - Addon state updated: selectedAddons += "demo" │
│ │
│ app/page.tsx already imports DemoHero component │
│ Files are now in place for generation │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Step 3: Docker Compose Generation │
│ ────────────────────────────────────────────────────────────│
│ packages/engine/emit/docker.ts │
│ │
│ collectDockerFragments(state): │
│ - For "mongodb" addon: │
│ Load templates/databases/mongodb/docker/ │
│ docker-compose.mongo.yml │
│ Add to state.dockerFragments │
│ │
│ collectDockerVolumes(state): │
│ - For "mongodb": add mongo_data volume │
│ │
│ mergeDockerComposeDev(state): │
│ Base services: │
│ ├── app: │
│ │ ├── build: {context: ., dockerfile: Dockerfile} │
│ │ ├── command: pnpm dev │
│ │ ├── ports: ["3000:3000"] │
│ │ ├── volumes: [.:/app, /app/node_modules] │
│ │ ├── environment: │
│ │ │ ├── NODE_ENV: development │
│ │ │ └── MONGODB_URI: mongodb://mongodb:27017/BaseCompose │
│ │ └── depends_on: [mongodb] │
│ └── mongodb: │
│ ├── image: mongo:7 │
│ ├── ports: ["27017:27017"] │
│ └── volumes: [mongo_data:/data/db] │
│ │
│ mergeDockerComposeProd(state): │
│ Same base but with: │
│ ├── restart: always │
│ ├── MONGO_INITDB_ROOT_USERNAME: root │
│ ├── MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD} │
│ └── NODE_ENV: production │
│ │
│ writeDockerCompose(state): │
│ - Write docker-compose.dev.yml │
│ - Write docker-compose.prod.yml │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Step 4: Environment Variables │
│ ────────────────────────────────────────────────────────────│
│ packages/engine/emit/env.ts │
│ │
│ collectAddonEnv(state): │
│ For each addon: │
│ - Load addon/env.ts │
│ - Parse export const env = {...} │
│ - Add to state.env │
│ │
│ MongoDB env.ts exports: │
│ { MONGODB_URI, MONGODB_ROOT_USERNAME, │
│ MONGODB_ROOT_PASSWORD } │
│ │
│ writeEnvExample(state): │
│ Create .env.example with all addon env vars: │
│ │
│ MONGODB_URI=mongodb://mongodb:27017/BaseCompose │
│ MONGODB_ROOT_USERNAME=root │
│ MONGODB_ROOT_PASSWORD=example │
│ GITHUB_ID= │
│ GITHUB_SECRET= │
│ NEXTAUTH_URL=http://localhost:3000 │
│ NEXTAUTH_SECRET= │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Step 5: Additional Files │
│ ────────────────────────────────────────────────────────────│
│ │
│ Create .gitignore: │
│ node_modules/ │
│ .next/ │
│ .env.local │
│ .env*.local │
│ .DS_Store │
│ │
│ Copy SETUP.md from templates/shared/README_SETUP.md │
│ - Quick start instructions │
│ - Project structure overview │
│ - Development vs production modes │
│ - Common commands │
│ - Troubleshooting guide │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Step 6: Archive as tar.gz │
│ ────────────────────────────────────────────────────────────│
│ │
│ Using tar.create(): │
│ - Gzip compression enabled │
│ - Archive path: /tmp/BaseCompose-XXXXX/project.tar.gz │
│ - Includes entire project directory │
│ │
│ Read buffer into memory: │
│ - fs.readFileSync(zipPath) → Buffer │
│ │
│ Return to API route │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Final Response │
│ ────────────────────────────────────────────────────────────│
│ │
│ HTTP 200 OK │
│ Content-Type: application/gzip │
│ Content-Disposition: attachment; filename="BaseCompose-stack..."│
│ Body: tar.gz Buffer │
│ │
│ Browser downloads: BaseCompose-stack.tar.gz │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ User Extracts & Runs │
│ ────────────────────────────────────────────────────────────│
│ │
│ $ tar -xzf BaseCompose-stack.tar.gz │
│ $ cd project │
│ │
│ $ pnpm install │
│ $ pnpm dev │
│ │
│ OR │
│ │
│ $ docker compose -f docker-compose.dev.yml up │
│ │
│ ✅ Running at http://localhost:3000 │
│ with hot reload and all features enabled │
└─────────────────────────────────────────────────────────────┘
- Why: Reliable, reproducible, version-controlled
- How: Copy real files from templates/, merge configs
- Benefit: Users get guaranteed working projects
- Why: Optimized for different use cases
- Dev: Hot reload, no auth, local development DX
- Prod: Secure, persistent, auto-recovery
- MongoDB:
app/lib/db/mongodb.ts - Auth.js:
app/api/auth/[...nextauth].ts - Demo:
app/lib/components/demo-hero.tsx - Benefit: Predictable, easy to extend
- Each addon exports:
export const env = { ... } - Generator parses and documents in
.env.example - User fills in values before running
- Every generated project includes
SETUP.md - Clear instructions for dev and prod modes
- Troubleshooting for common issues
- Generation Time: ~500ms (framework copy + addons)
- Archive Size: ~20-30 MB tar.gz (includes node_modules)
- Extraction Time: ~2-5 seconds
- First Dev Run: ~10-15 seconds (pnpm install, Next.js prep)
- First Docker Run: ~30-60 seconds (build + startup)
- Template missing: Warns but continues
- Docker fragment parse error: Warns but continues
- Env.ts parse error: Skips, documents in .env.example
- File copy error: Throws and stops generation
- Archive error: Throws to API (500 response)
- Create
templates/category/addon-name/folder - Add addon files in standard locations
- Optionally add
docker/docker-compose.addon.yml - Add
env.tswith export const env = {...} - Update
stack-config.tsto register addon - Update
determineAddons()logic in generate.ts - Generator automatically includes it
- Create
templates/frameworks/framework-name/ - Create
base/(scaffold) anddocker/(container) - Update
copyFrameworkBase()in copy.ts - Update type definitions to include framework
- Generator ready for new framework
- Modify
determineAddons()for business logic - Modify Docker merge functions for custom compose
- Modify
copyAddonFiles()for custom file placement - All changes in
packages/engine/