A highly interactive, Cyberpunk/Matrix-themed personal portfolio website built with React, Three.js (via Spline), and Tailwind CSS. It features a responsive layout, a custom 3D robot interaction, and a detailed timeline of robotics and AI projects.
This portfolio went through several design iterations before arriving at its current form:
-
V1 — Futuristic Acrylic: Started with a sci-fi aesthetic featuring acrylic-style panels and holographic effects. It looked cool, but felt generic and overused.
-
V2 — Glassmorphism + Rounded Corners: Pivoted to a softer approach with frosted-glass cards and rounded UI elements. This improved readability but ended up looking too "template-y" and lacked personality.
-
V3 — Refined Minimalism (Current): Stripped back the visual noise. The new direction uses a minimalist foundation with intentional color pops—keeping the interface clean while still feeling bold and expressive. The result: a design that breathes, stands out, and doesn't scream "AI-generated portfolio."
https://alexbuildstech.github.io/portfolio/
- Frontend: React, TypeScript, Vite
- Styling: Tailwind CSS, shadcn/ui
- 3D/Animation: Spline (React Spline), Framer Motion
- Routing: React Router DOM (HashRouter)
- Testing: Vitest, React Testing Library, happy-dom
During the development of this portfolio, we encountered and solved several technical challenges:
- Problem: The
jsdomenvironment in Vitest struggled with ESM modules, specifically causingERR_REQUIRE_ESMerrors when processing certain dependencies likehtml-encoding-snifferand@splinetool/react-spline. - Solution: Migrated the test environment to
happy-dom. This lightweight DOM implementation handled the ESM interop much better. We also mocked heavy visual components (Spline,MatrixRain) insetup.tsto avoid WebGL errors in the headless test environment.
- Problem: The 3D robot was designed to "look at" the mouse cursor. On mobile devices, there is no persistent cursor, making the robot static and unresponsive.
- Solution: Implemented
onTouchMoveandonTouchStartevent handlers in a wrapperdiv. These handlers capture touch coordinates and dispatch validmousemoveevents to the underlying Spline canvas, allowing users to "drag" anywhere on the screen to control the robot's gaze.
- Problem 1 (Routing): Single Page Applications (SPAs) using
BrowserRouter(History API) return 404 errors when visiting sub-paths (e.g.,/contact) directly on static hosts like GitHub Pages. - Problem 2 (Assets): If the repository is not at the root domain, asset paths (
/assets/...) break. - Solution:
- Switched to
HashRouter, which uses the URL hash (/#/contact) to manage routing on the client side, bypassing server-side routing issues. - Updated
vite.config.tswithbase: "./", ensuring all asset requests are relative to theindex.htmllocation.
- Switched to
- Home: Introduction and animated 3D/Matrix landing.
- About: Timeline of projects (Nova Humanoid, Assistive Tech) with awards and links.
- Contact: Minimalist contact information.
- Clone the repository:
git clone https://github.com/yourusername/your-repo.git
- Install dependencies:
npm install
- Start the development server:
npm run dev
- Run tests:
npm test