Skip to main content

Technology stack

Wits World uses TypeScript across the Web application, API, shared packages, and documentation configuration. npm workspaces manage these projects from the repository root while keeping their builds separate.

The repository specifies Node.js 24.14.1 and npm 11.18.0. Use the checked-in .nvmrc and packageManager setting for a compatible setup.

Overview​

  • Web application: React, Vite, and Wouter provide the screens and navigation. Interface components, Mapbox, and offline storage support interaction, campus maps, and pending attempts.
  • API and database: Fastify handles requests, PostgreSQL and PostGIS store game state and perform spatial calculations, and Sharp processes images.
  • Shared services: Auth0 connects browser sign-in with API authentication. Redis supports shared quotas and gameplay coordination across API processes.
  • Shared packages: Common battle rules and Player Name validation keep application behaviour consistent.
  • Project tools: Verification tools check the implementation, and Docusaurus publishes the documentation.

Application stack​

Web application​

React, Vite, and Wouter​

React 19 provides the component model for Player and Author screens. Shared components let forms, card displays, navigation, and loading states follow the same patterns across features.

Vite 8 runs the Web development server and builds the production browser bundle. Wouter maps application URLs to screens and supports navigation within the single-page application. Together, they keep interface development and routing in the Web workspace.

Interface components​

React Aria Components supplies controls with keyboard interaction, focus management, and accessible semantics. @internationalized/date provides structured date and time values used by the Author scheduling controls. Application styling and date/time policy remain in Wits World.

Phosphor Icons provides a consistent icon set. Motion supports transitions such as card evolution, with reduced-motion handling, while Sonner presents toast notifications. Persistent results and validation messages also appear in the relevant screen.

Mapbox GL JS​

Mapbox GL JS provides the interactive map renderer and 3D basemap support. A shared adapter lets Explore and Author maps reuse the same rendering code.

Mapbox integration covers styles, overlays, and provider behaviour.

Offline storage and service worker​

IndexedDB stores issued challenge packs, local attempts, and reconciliation receipts. The idb library provides an asynchronous interface and transactions for those related records, helping the Web recover pending work after a reload.

vite-plugin-pwa integrates the application's service worker and installable manifest with the Vite build. The worker caches the application shell and build assets; challenge records use their separate IndexedDB store. Offline play defines how pending attempts are reconciled with the API.

API and database​

Fastify and API plugins​

Fastify 5 hosts the HTTP API. Routes define request and response schemas, while feature services handle gameplay and persistence. This structure makes routes testable through Fastify's request-injection interface.

The Swagger plugins generate OpenAPI documentation from the route schemas, keeping the HTTP reference connected to the implementation. The CORS plugin controls permitted browser origins. The WebSocket plugin adds live battle connections to the same API application.

TypeScript checks the API code during development and builds. tsx runs the TypeScript development server. Runtime schemas still validate incoming requests; compile-time types alone cannot check network input.

PostgreSQL, PostGIS, and pg​

PostgreSQL stores relational game data, including ownership, challenge attempts, and match history. Foreign keys, uniqueness constraints, transactions, and locks support operations that must keep several records consistent.

PostGIS adds spatial types and queries for event distance, reviewed placement sites, and campus boundaries. Geography-based distance calculations support metre-based rules in the API.

The pg driver gives services direct control over parameterised SQL, connection pools, and transaction boundaries. Schema changes use versioned SQL migrations. The database overview links the domain designs.

Sharp​

Sharp processes uploaded profile images on the API. The implementation checks the input, applies orientation, crops and resizes it, and produces a consistent 256 × 256 JPEG before storing the profile image.

Repository artwork scripts also use Sharp. Keeping this processing on the server or in tooling gives the application a consistent image format and size.

Shared services​

Auth0 and token verification​

The Auth0 React SDK provides browser authentication support; jose handles JWT verification in the API. Using maintained authentication libraries keeps this code focused on Wits World account and permission rules.

Auth0 integration covers authentication flows, client configuration, and account-management requests; Security covers validation and permissions.

Upstash Redis​

The Upstash SDKs connect the API to Redis-backed request limits and gameplay coordination. Shared counters allow quotas to apply across API instances.

Upstash Redis integration covers the exchanged records and operational links; Rate limits defines the operation-specific policies.

Shared packages​

packages/game-rules contains the battle engine used by CPU, asynchronous, and live matches. It operates on validated snapshots and returns transitions; API services supply its inputs and persist the results. Keeping battle transitions in one package avoids separate implementations for each match mode.

packages/account-policy contains Player Name validation shared by the Web and API. Browser feedback and server validation therefore use the same naming rules.

Build the shared packages before dependent applications. Getting started gives the setup commands.

Development and verification​

TypeScript checks application and package types. ESLint applies static code rules, and Prettier keeps formatting consistent across workspaces.

Vitest runs unit, component, route, and database tests within the TypeScript toolchain. React Testing Library and jsdom exercise Web interface behaviour; Fastify injection exercises HTTP routes. fake-indexeddb provides controlled offline-storage tests.

Database integration tests use isolated PostGIS databases. PR validation supplies PostgreSQL 17 with PostGIS 3.5. Playwright covers real-browser journeys, where browser behaviour and interactions need their own checks.

Testing strategy and Continuous integration define commands and test scope.

Documentation​

Docusaurus builds the public site from Markdown and MDX. It supplies navigation, page rendering, and a separate static build, allowing documentation changes to be reviewed alongside application changes.

Mermaid keeps diagrams editable as text next to their supporting references. Local search generates its index with the site and runs queries in the browser.

Dependency versions​

Workspace package.json files declare dependencies; package-lock.json records resolved versions. Use npm ci for a reproducible installation. Those files remain the complete dependency and version reference.

See System architecture for application responsibilities and hosting, and Integrations for external service connections.

AI declaration: Prepared and updated with assistance from ChatGPT-Web[GPT-5.6 Thinking], ChatGPT-Web[GPT-5.6 Sol], Codex-CLI[GPT-5], Codex[GPT-5], Codex-CLI[gpt-5.6-sol medium], Codex-CLI[GPT-6], and Codex[GPT-6].