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 inUtils/Time.ts→ UI components viaEventBus.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 inserver/index.tsserves the build; no database or external network calls are made - File responsibilities:
src/Application/Application.ts– bootstraps the appsrc/Application/Renderer.ts– WebGL scene setup, shader attachmentsrc/Application/World/World.ts– scene population, object managementsrc/Application/Utils/Resources.ts– GLB/audio asset fetchingsrc/Application/Utils/Sizes.ts– viewport dimensionssrc/Application/Utils/Time.ts– delta time, animate loopsrc/Application/Audio/AudioManager.ts– audio playback controlsrc/Application/UI/EventBus.ts– component communication- Hub/module blast radius:
Renderer.tsandWorld.tscarry the widest impact; altering shader code requires touching bothvertex.glslandfragment.glslpaths, and model changes ripple throughResources.tsandWorld.tsloading 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.