Technology Overview
Core Stack
| Technology | Version | Purpose |
|---|---|---|
| SolidJS | 1.9.10 | Reactive UI framework |
| Vite | 7.1.12 | Build tool and dev server |
| TypeScript | 6.0.0-beta | Type safety |
| TailwindCSS | 4.1.18 | Utility-first CSS |
| TanStack Query | 5.90.23 | Server state management |
| Firebase | 12.0.0 | Authentication |
frontend/src/ts/
Why SolidJS?
Solid was chosen for its performance characteristics:- Fine-grained reactivity: Updates only what changes, no virtual DOM
- Compiled output: No runtime overhead
- Small bundle size: Efficient for a typing test application
- React-like syntax: Familiar JSX with better performance
Project Structure
Application Entry Point
The application bootstraps through a carefully orchestrated initialization sequence:frontend/src/ts/index.ts
Component Architecture
Component Mounting System
Solid components are mounted to specific mount points in the HTML:frontend/src/ts/components/mount.tsx:1
Component Types
1. Page Components (components/pages/)
- Top-level route components
- Example:
ProfilePage,AboutPage - Handle data fetching via TanStack Query
components/layout/)
- Structural components
- Example:
Footer,Overlays
components/common/)
- Reusable UI components
- Shared across pages
components/modals/)
- Dialog and modal implementations
- Centralized in
Modalscomponent
State Management
Monkeytype uses a multi-layered state management approach:1. Solid Signals (Reactive State)
frontend/src/ts/signals/
2. Solid Stores (Complex State)
frontend/src/ts/stores/
3. Observable Pattern (Legacy State)
frontend/src/ts/observables/
4. TanStack Query (Server State)
frontend/src/ts/queries/
- Automatic caching
- Background refetching
- Optimistic updates
- Request deduplication
5. Local Storage (Persistent State)
frontend/src/ts/config.ts:1
6. IndexedDB (Local Database)
frontend/src/ts/db.ts:1
Routing
Monkeytype uses a custom routing system rather than a traditional SPA router:frontend/src/ts/controllers/route-controller.ts
- Typing test needs to stay mounted (preserve state)
- Avoids full component unmount/remount
- Optimized for the specific use case
API Client (APE)
The frontend uses ts-rest for type-safe API calls:frontend/src/ts/ape/
- Full type safety from backend to frontend
- Autocomplete for all endpoints
- Compile-time error checking
- Single source of truth (contracts package)
Build System (Vite)
Development Build
frontend/vite.config.ts:327
- Hot Module Replacement (HMR)
- Fast refresh for Solid components
- TypeScript type checking
- Instant server start (under 1 second)
Production Build
frontend/vite.config.ts:217
- Code splitting by route
- Tree shaking unused code
- Asset optimization (images, fonts)
- Vendor chunk splitting
- Brotli compression
Bundle Analysis
frontend/vite.config.ts:259
vendor.js- Third-party librariesvendor-firebase.js- Firebase SDKvendor-sentry.js- Error trackingmonkeytype-packages.js- Shared packages[page].js- Page-specific code
Performance Optimizations
1. Lazy Loading
2. Memoization
3. Virtual Scrolling
4. PWA Caching
frontend/vite.config.ts:157
Testing
Unit Tests (Vitest)
Next Steps
- Backend Architecture - API and server design
- Database Architecture - Data models and storage