← All work
Case study · 2023

3D Portfolio

A portfolio site with an interactive 3D scene built on React Three Fiber, plus routed pages and an EmailJS contact form.

ReactViteThree.jsReact Three FiberDreiTailwind CSSLive site ↗Source ↗
portfolio-3d-pearl.vercel.app
3D Portfolio — screenshot of the live site

Overview

A portfolio built with Vite, React and Three.js, using 3D models from Sketchfab rendered through React Three Fiber.

What I built

  • 3D models kept in src/models and rendered in a React Three Fiber canvas with Drei helpers and react-spring animation.
  • Pages in src/pages with React Router, plus shared Navbar, Footer, HomeInfo, CTA, Loader and Alert components.
  • Experience timeline with react-vertical-timeline-component.
  • Contact form sent through EmailJS, with an alert for success and error states.

Architecture

Client-only app with a 3D canvas on top of routed pages.

flowchart LR
  subgraph client["Browser"]
    router["React Router pages"]
    canvas["R3F Canvas"]
    models["GLTF models"]
    ui["Navbar HomeInfo Timeline"]
  end
  subgraph ext["External"]
    ejs["EmailJS"]
  end
  router --> canvas
  canvas --> models
  router --> ui
  router -->|"contact form"| ejs

System design

Loading the home scene.

sequenceDiagram
  participant U as Visitor
  participant R as React app
  participant C as R3F Canvas
  U->>R: open home route
  R->>C: mount scene inside Suspense
  C-->>U: Loader while models load
  C-->>U: interactive 3D scene
  U->>C: drag to rotate
  C-->>R: current stage
  R-->>U: HomeInfo card for stage

Learnings

  • Large GLTF models dominate load time; compressing them matters more than JS bundle size here.
  • Suspense with a loader made the 3D load feel deliberate rather than broken.