The Problem

This repository addresses the challenge of delivering a high-fidelity, interactive 3D web portfolio that runs entirely in the browser. It combines React with WebGL rendering, GLB model imports, custom shaders, and spatial audio to present a technically dense showcase piece. The core tension is balancing visual richness with load performance and maintainable code across 120 files.

What This Does

This is a React‑driven 3D application rendered via WebGL. src/index.html is the HTML entry, served by server/index.ts (Express). Client execution starts at src/Application/UI/App.tsx, which imports src/Application/UI/index.ts and mounts the scene. src/Application/Renderer.ts sets up the WebGL context and references src/Application/Shaders/screen/fragment.glsl, src/Application/Shaders/screen/vertex.glsl, src/Application/Shaders/coffee/fragment.glsl, and src/Application/Shaders/coffee/vertex.glsl for material effects. The scene graph lives in src/Application/World/World.ts, populated by Environment.ts, Computer.ts, Cursor.ts, Decor.ts, and MonitorScreen.ts. Asset loading and lifecycle are managed by src/Application/Utils/Resources.ts, while src/Application/Utils/Sizes.ts and src/Application/Utils/Time.ts drive the render loop and window resizing. Audio is loaded from static/audio/ and coordinated by src/Application/Audio/AudioManager.ts and src/Application/Audio/AudioSources.ts. UI interactivity is provided by FreeCamToggle.tsx, HelpPrompt.tsx, InfoOverlay.tsx, and MuteToggle.tsx, all wired through src/Application/UI/EventBus.ts. src/Application/Utils/EventEmitter.ts and src/Application/Utils/Debug.ts support diagnostic and event plumbing. No single file owns the full pipeline; Renderer.ts and World.ts act as hubs—changes to model formats or shader logic affect both.

How It Is Wired

  • Entry points: server/index.ts, src/Application/UI/App.tsx, src/Application/UI/index.ts, src/index.html
  • Execution flow: App.tsx → Renderer.ts → World.ts → Resources.ts (model/audio load) → render loop in Utils/Time.ts → UI components via EventBus.ts
  • What the code touches outside itself: Static assets in static/models/, static/audio/, static/textures/, and GLSL shaders are read at runtime; the Express server in server/index.ts serves the build; no database or external network calls are made
  • File responsibilities:
  • src/Application/Application.ts – bootstraps the app
  • src/Application/Renderer.ts – WebGL scene setup, shader attachment
  • src/Application/World/World.ts – scene population, object management
  • src/Application/Utils/Resources.ts – GLB/audio asset fetching
  • src/Application/Utils/Sizes.ts – viewport dimensions
  • src/Application/Utils/Time.ts – delta time, animate loop
  • src/Application/Audio/AudioManager.ts – audio playback control
  • src/Application/UI/EventBus.ts – component communication
  • Hub/module blast radius: Renderer.ts and World.ts carry the widest impact; altering shader code requires touching both vertex.glsl and fragment.glsl paths, and model changes ripple through Resources.ts and World.ts loading logic. The module graph is tree‑structured with no detected cycles, but the two hubs mean a change in rendering strategy or world geometry requires coordinated edits.

How To Use It

# Clone the repository
git clone https://github.com/moses-y/portfolio-website

# Install dependencies
npm i

# Run the local dev server
npm run dev

To serve a production build:

npm run build
npm start

Real-World Use

A developer wants to add a new 3D model to the portfolio. They place the .glb file in static/models/, update src/Application/Utils/Resources.ts to include the new import path, and register the object in src/Application/World/World.ts. The render loop automatically picks up the new asset without rebuilding the bundler, thanks to the modular Resources.ts loader. If they want to toggle visibility via the UI, they add a toggle component that dispatches through EventBus.ts, which World.ts listens to for scene-graph updates.

Code Health & Issues

  • Medium/SDLC - No CI/CD pipeline detected - no automated build/test gate - .github/ or CI config missing
  • Low/Risk - Dependencies declared without a lockfile - non-reproducible builds - package.json

No lockfile (package-lock.json or yarn.lock) is present, so npm ci cannot guarantee identical installs across environments. No .github/workflows/ directory exists, so there are no automated lint, test, or build gates. The single test file found has not been mapped to a CI job.

The Bottom Line

This repo is a capable, self-contained 3D portfolio showcase that demonstrates solid WebGL/React integration and thoughtful asset organization. Its main liabilities are the absent lockfile and missing CI/CD, which raise the cost of reproducibility and safe collaboration. It’s best suited for individual developers or small teams who need a polished interactive demo and are comfortable managing dependencies and builds manually.