Design Decisions
Technology choices for the BISO Sites monorepo — stack summary and rationale.
Design Decisions
Why the monorepo is built the way it is: stack overview and the main technology choices. For security, performance, and deployment concerns, see Quality and operations.
Technology stack summary
Frontend
| Technology | Role |
|---|---|
| Next.js (App Router) | Framework for all apps |
| React | UI |
| TypeScript | Types across the repo |
| Tailwind CSS | Styling |
| shadcn/ui (via @repo/ui) | Component primitives |
Backend and tooling
| Technology | Role |
|---|---|
| Appwrite | Database, auth, storage |
| Node.js / Bun | Runtime and package manager |
| Turborepo | Build orchestration and caching |
| ESLint / Biome (Ultracite) | Lint and format |
| Fumadocs | This docs site |
Why Turborepo?
Decision: Turborepo for monorepo builds (versus heavier alternatives).
Reasoning: Simple configuration, strong caching, works well with Next.js, fast incremental builds, good developer experience.
Why Bun?
Decision: Bun for installs and scripts (workspace root).
Reasoning: Very fast installs, npm-compatible ecosystem, built-in TypeScript execution where useful, active maintenance.
Why Appwrite?
Decision: Appwrite as the primary backend.
Reasoning: Self-hostable for data ownership, open source, solid TypeScript story, integrated database/auth/storage/realtime, and less proprietary lock-in than some hosted-only BaaS options.
Why Next.js App Router?
Decision: App Router for all Next.js apps.
Reasoning: Server Components by default, colocated data fetching, Server Actions for mutations, file-based routing aligned with the framework’s direction.
Why dependency injection in packages?
Decision: Inject infrastructure (for example DB clients) into package functions instead of importing framework-specific modules inside @repo/payment and similar packages.
Reasoning: Keeps packages testable, portable, and explicit about dependencies. See Dependency injection for patterns used in the repo.
