Architecture Overview
Our monorepo is built on modern web technologies with a focus on code reuse, type safety, and developer experience.
Tech Stack
Frontend
- Framework: Next.js 16 (App Router) for web and admin; docs uses Next.js 15
- UI Library: React 19
- Language: TypeScript 5.x
- Styling: Tailwind CSS
- Component Library: shadcn/ui (Radix UI primitives)
- Animation: Framer Motion
- Forms: React Hook Form + Zod validation
Backend
- Database: PostgreSQL (via Supabase)
- Database Client: postgres.js (via
@uwdsc/db); repositories extendBaseRepositoryfrom@uwdsc/db/baseRepository - Migrations: db-migrate (migrations in
packages/server/db); run from root withpnpm migrate - Auth: Supabase Auth (clients from
@uwdsc/db;AuthServicefrom@uwdsc/core) - Storage: Supabase Storage
- API: Next.js API Routes
Monorepo Tooling
- Package Manager: pnpm (with workspaces)
- Build System: Turborepo
- Code Quality: ESLint, Prettier, TypeScript
Architecture Principles
1. Atomic Design System
We follow atomic design principles:
Atoms (packages/ui) β Molecules (app components) β Organisms β Pages- Atoms: Basic UI components (Button, Card, Input)
- Molecules: Composed components with specific functionality
- Organisms: Complex UI sections
- Pages: Full page layouts
2. Layered Architecture
Clean separation of concerns:
React Components β Client API β API Routes β Services β Repository β DatabaseEach layer has a specific responsibility:
- Components: UI and user interaction
- Client API: Type-safe API wrappers
- API Routes: HTTP request handling
- Services: Business logic
- Repository: Data access layer
- Database: Data persistence
3. Shared-First Approach
Common functionality lives in shared packages:
- UI components in
packages/ui(@uwdsc/ui) - Backend:
@uwdsc/db(connection, Supabase, BaseRepository),@uwdsc/core(shared services),@uwdsc/admin(admin-only services) - Config in
packages/eslint-configandpackages/typescript-config
4. Type Safety Everywhere
- TypeScript across the entire stack
- Zod schemas for runtime validation
- pg with raw SQL queries for database access
- Shared types between frontend and backend
Package Organization
Apps (apps/)
Frontend applications:
apps/
βββ web/ # Main UWDSC website and member applications
βββ admin/ # Admin dashboard and CXC application/review system
βββ docs/ # This documentation siteShared Packages (packages/)
Reusable code shared across apps:
packages/
βββ ui/ # Design system (@uwdsc/ui)
βββ common/ # Shared types and utils (@uwdsc/common)
βββ server/ # Backend
β βββ db/ # @uwdsc/db - Postgres, Supabase, BaseRepository, migrations
β βββ core/ # @uwdsc/core - Shared services (auth, profile, application, etc.)
β βββ admin/ # @uwdsc/admin - Admin-only services (e.g. member listing)
βββ eslint-config/ # Shared ESLint config
βββ typescript-config/ # Shared TypeScript configDependency Flow
Apps depend on packages, but packages never depend on apps. This ensures:
- Clear dependency direction
- Packages can be used independently
- No circular dependencies
Build Process
Turborepo orchestrates the build process:
- Dependency Graph: Turborepo analyzes dependencies
- Topological Ordering: Builds packages in correct order
- Parallel Execution: Runs independent tasks in parallel
- Caching: Skips unchanged packages
# Build all packages in optimal order
pnpm build
# Turborepo handles:
# 1. Building packages/ui first
# 2. Building server packages
# 3. Building apps lastDevelopment Workflow
# 1. Make changes to any package
# 2. Turborepo detects changes
# 3. Only affected packages rebuild
# 4. Hot module replacement in appsNext Steps
- Monorepo Structure - Detailed package breakdown
- Design System - UI component architecture
- API Architecture - Backend patterns