ArchitectureOverview

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 15 (App Router)
  • UI Library: React 19
  • Language: TypeScript 5.7
  • 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: pg (node-postgres) with raw SQL
  • Migrations: db-mate with SQL files
  • Auth: Supabase Auth
  • 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 β†’ Database

Each 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
  • Backend utilities in packages/server/core
  • Config in packages/eslint-config and packages/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 that users interact with:

apps/
β”œβ”€β”€ web/          # Main UWDSC website
β”œβ”€β”€ cxc/          # CxC AI hackathon app
└── docs/         # This documentation site

Shared Packages (packages/)

Reusable code shared across apps:

packages/
β”œβ”€β”€ ui/                    # Design system (atoms)
β”œβ”€β”€ server/                # Backend services
β”‚   β”œβ”€β”€ core/             # Shared backend utilities
β”‚   β”œβ”€β”€ web/              # Web app backend
β”‚   └── cxc/              # CxC app backend
β”œβ”€β”€ eslint-config/         # Shared ESLint config
└── typescript-config/     # Shared TypeScript config

Dependency 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:

  1. Dependency Graph: Turborepo analyzes dependencies
  2. Topological Ordering: Builds packages in correct order
  3. Parallel Execution: Runs independent tasks in parallel
  4. 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 last

Development Workflow

# 1. Make changes to any package
# 2. Turborepo detects changes
# 3. Only affected packages rebuild
# 4. Hot module replacement in apps

Next Steps