# Milestone 2: Web Stack Selection **Status**: Decided **Goal**: Choose backend technologies for the developer portal and app store API. ## Decision **Go** with the following stack: ``` Language: Go 1.22+ Framework: Chi (lightweight, idiomatic) Database: SQLite via modernc.org/sqlite (pure Go, no CGO) Migrations: golang-migrate Validation: go-playground/validator Auth: Custom JWT + OAuth2 Deployment: Single Docker container on Synology NAS ``` ### Rationale 1. **NAS-friendly** - Tiny Docker image (~15MB), low RAM (~30-50MB) 2. **Cross-compilation** - Easy build for ARM64 or AMD64 Synology models 3. **Pure Go SQLite** - `modernc.org/sqlite` requires no CGO, cross-compiles easily 4. **Single container** - Go binary + SQLite + Litestream in one image 5. **Standard library** - HTTP, JSON, crypto all built-in ### Target Deployment ``` Synology NAS (Docker) ├── mosis-portal container (~15MB image) │ ├── Go binary │ ├── SQLite database (WAL mode) │ └── Litestream backup └── Volumes ├── /volume1/mosis/data/portal.db ├── /volume1/mosis/backups/ └── /volume1/mosis/packages/ ``` --- ## Overview The web stack powers the developer portal, app store API, and telemetry ingestion. This decision affects development speed, hosting costs, and long-term maintenance. --- ## Requirements ### Functional - REST API for developer portal - File upload handling (app packages) - Authentication (OAuth2, API keys) - Database integration - Background jobs (review queue, notifications) - WebSocket support (optional, for real-time updates) ### Non-Functional - Handle 1000+ developers initially - Scale to 10,000+ apps - 99.9% uptime target - < 200ms API response time (p95) - Secure by default --- ## Options Analysis ### Option A: Node.js + TypeScript #### Stack ``` Runtime: Node.js 20 LTS Language: TypeScript Framework: Fastify or Hono ORM: Prisma or Drizzle Validation: Zod Auth: Lucia or custom JWT ``` #### Pros | Advantage | Details | |-----------|---------| | Fast development | Large ecosystem, familiar syntax | | Type safety | TypeScript catches errors early | | Easy hiring | Many JS/TS developers | | Ecosystem | npm has libraries for everything | | Hosting | Vercel, Railway, Render, any VPS | #### Cons | Disadvantage | Details | |--------------|---------| | Single-threaded | Need clustering for CPU tasks | | Memory usage | Higher than compiled languages | | Callback complexity | Async can get messy | #### Example Structure ``` src/ ├── index.ts ├── routes/ │ ├── auth.ts │ ├── apps.ts │ └── telemetry.ts ├── services/ │ ├── auth.service.ts │ └── storage.service.ts ├── db/ │ ├── schema.ts │ └── client.ts └── utils/ ``` #### Hosting Cost Estimate | Service | Cost/month | |---------|------------| | Railway (starter) | $5-20 | | Vercel Pro | $20 | | VPS (4GB) | $20-40 | --- ### Option B: Go #### Stack ``` Language: Go 1.22+ Framework: Chi, Echo, or Gin ORM: sqlc or GORM Validation: go-playground/validator Auth: Custom JWT ``` #### Pros | Advantage | Details | |-----------|---------| | Performance | Fast, low memory | | Single binary | Easy deployment | | Concurrency | Goroutines handle load well | | Standard library | HTTP, JSON, crypto built-in | #### Cons | Disadvantage | Details | |--------------|---------| | Verbose | Error handling boilerplate | | Smaller ecosystem | Fewer ready-made solutions | | Learning curve | Different paradigm | #### Example Structure ``` cmd/ ├── server/ │ └── main.go internal/ ├── api/ │ ├── handlers/ │ ├── middleware/ │ └── routes.go ├── domain/ │ ├── app.go │ └── developer.go ├── repository/ │ └── postgres/ └── service/ ``` #### Hosting Cost Estimate | Service | Cost/month | |---------|------------| | Fly.io (shared) | $5-15 | | Cloud Run | Pay per use | | VPS (2GB) | $10-20 | --- ### Option C: Rust + Axum #### Stack ``` Language: Rust Framework: Axum ORM: sqlx or SeaORM Validation: validator crate Auth: Custom JWT ``` #### Pros | Advantage | Details | |-----------|---------| | Maximum performance | Fastest option | | Memory safety | No runtime errors | | Single binary | Easy deployment | | Long-term reliability | Compiler catches bugs | #### Cons | Disadvantage | Details | |--------------|---------| | Steep learning curve | Borrow checker takes time | | Slower development | More code to write | | Smaller ecosystem | Fewer web libraries | | Compile times | Can be slow | #### Example Structure ``` src/ ├── main.rs ├── api/ │ ├── mod.rs │ ├── handlers/ │ └── middleware/ ├── domain/ ├── repository/ └── service/ ``` #### Hosting Cost Estimate | Service | Cost/month | |---------|------------| | Fly.io | $5-10 | | Shuttle | Free tier available | | VPS (1GB) | $5-10 | --- ### Option D: .NET (ASP.NET Core) #### Stack ``` Language: C# Framework: ASP.NET Core 8 ORM: Entity Framework Core Validation: FluentValidation Auth: ASP.NET Identity ``` #### Pros | Advantage | Details | |-----------|---------| | Enterprise-ready | Battle-tested at scale | | Great tooling | Visual Studio, debugging | | Performance | Very fast (Kestrel) | | Full-featured | Auth, validation, DI built-in | #### Cons | Disadvantage | Details | |--------------|---------| | Heavier runtime | Larger container images | | Microsoft ecosystem | May feel locked in | | Verbose | More boilerplate | #### Hosting Cost Estimate | Service | Cost/month | |---------|------------| | Azure App Service | $15-50 | | VPS (4GB) | $20-40 | --- ## Evaluation Matrix | Criteria | Weight | Node.js | Go | Rust | .NET | |----------|--------|---------|-----|------|------| | Dev speed | 25% | 9 | 7 | 5 | 7 | | Performance | 20% | 6 | 9 | 10 | 8 | | Hosting cost | 15% | 7 | 9 | 9 | 6 | | Ecosystem | 15% | 9 | 7 | 6 | 8 | | Team familiarity | 15% | ? | ? | ? | ? | | Long-term maintenance | 10% | 7 | 8 | 9 | 8 | | **Weighted Score** | | **7.4** | **7.8** | **7.2** | **7.3** | *Team familiarity needs to be filled in based on actual experience* --- ## Framework Comparison ### Node.js Frameworks | Framework | Req/sec | Features | Learning Curve | |-----------|---------|----------|----------------| | Express | 15k | Minimal, flexible | Easy | | Fastify | 45k | Fast, schema validation | Medium | | Hono | 50k | Ultra-light, edge-ready | Easy | | NestJS | 20k | Full-featured, Angular-like | Steep | ### Go Frameworks | Framework | Req/sec | Features | Learning Curve | |-----------|---------|----------|----------------| | net/http | 60k | Standard library | Medium | | Chi | 55k | Lightweight router | Easy | | Gin | 50k | Popular, middleware | Easy | | Echo | 55k | Similar to Gin | Easy | --- ## Prototype Plan ### Phase 1: Build minimal API in top 2 choices Endpoints to implement: ``` POST /auth/register POST /auth/login GET /apps POST /apps POST /apps/:id/versions ``` ### Phase 2: Benchmark - Requests per second - Memory usage under load - Development time tracking - Code complexity comparison ### Phase 3: Decision Based on: - Benchmark results - Developer experience during prototype - Hosting cost analysis --- ## Recommendation **Primary: Go with Chi/Echo** - Best balance of performance and simplicity - Low hosting costs - Single binary deployment - Good enough ecosystem for our needs **Fallback: Node.js with Hono/Fastify** - If Go feels too slow to develop in - Larger ecosystem for edge cases - More developers familiar with it --- ## Deliverables - [x] Final selection with rationale - [ ] Project structure template - [ ] Development environment setup guide - [ ] Base Go project scaffolding --- ## Open Questions 1. Do we need GraphQL or is REST sufficient? 2. Do we need real-time features (WebSocket)? 3. What's the team's current language experience? 4. Any preference for specific cloud providers? --- ## References - [TechEmpower Benchmarks](https://www.techempower.com/benchmarks/) - [Go vs Node.js comparison](https://blog.logrocket.com/node-js-vs-golang/) - [Fastify benchmarks](https://fastify.dev/benchmarks/)