Skip to content

Repository files navigation

Threejs React Sofa Configurator

A real-time, photorealistic 3D product configurator running entirely in the browser. Built with React 18, TypeScript, Three.js and GSAP — no game engine, no server, no paid 3D service.

Three.js TypeScript React Vite GSAP Sass GitHub Pages

3D Sofa Configurator demo


Overview

E-commerce product pages are static. This project is the alternative: a fully interactive 3D product page where a customer rotates the product, swaps upholstery fabrics and wood finishes in real time, and exports a render of their configuration — all inside a browser tab, with no plugin and no backend.

The interesting part is not the sofa. It is the engine layer underneath: a framework-agnostic set of TypeScript classes that own the WebGL context, the asset pipeline and GPU memory, with React kept strictly in the role of UI shell. That separation is what keeps a 3D app from leaking memory and tanking frame rate the moment it grows past a demo.

Key Features

Real-time PBR material swapping Fabric maps (albedo / normal / roughness) and wood tints are re-bound on the live scene graph without reloading the model.
Photorealistic lighting Image-based lighting via Three.js RoomEnvironment with ACES Filmic tone mapping and correct sRGB output encoding.
Memory discipline Every geometry, material and texture is explicitly disposed on unmount — no orphaned GPU allocations left behind.
Draw-call minimisation Shared material instances and a flattened scene graph keep the per-frame draw count low on integrated GPUs.
Adaptive texture quality Anisotropic filtering is clamped to the device's real maxAnisotropy instead of a hard-coded guess.
Screenshot export Captures the framebuffer and downloads the customer's configuration as an image.
Progressive loading Real byte-level progress from the GLTF loader drives the loading UI — not a fake timer.
Code-split by weight Three.js, GSAP and app code ship as separate chunks; the 3D engine is lazily imported so first paint never waits on WebGL.

Architecture

React never touches the WebGL context directly. It renders a <canvas>, hands the ref to the engine, and receives callbacks. Everything below src/engine/ is plain TypeScript and could be lifted into a Vue or Svelte app unchanged.

src/
├── engine/                  # Framework-agnostic 3D layer (no React imports)
│   ├── SceneManager.ts      # Renderer, camera, controls, RAF loop, resize, disposal
│   ├── ModelLoader.ts       # GLTF loading, progress reporting, auto-fit scaling
│   ├── TextureManager.ts    # Texture cache, colour-space + anisotropy handling
│   └── Configurator.ts      # Material mutation API (fabric / wood finish)
│
├── components/              # React UI shell
│   ├── Canvas/              # Mounts the canvas, owns the engine lifecycle
│   ├── UI/ConfiguratorPanel # Material picker + screenshot control
│   ├── UI/Loader            # Progress indicator
│   └── Header/  Footer/
│
├── constants/               # Fabric and wood option definitions
├── utils/asset.ts           # Host-agnostic asset URL resolution (see Deployment)
└── styles/                  # SCSS design tokens, mixins, reset

Why this split matters: the disposal contract lives in one place. When CanvasView unmounts, a single call tears down the renderer, cancels the animation frame, and frees every GPU resource. Spreading that responsibility across component render logic is the most common source of memory leaks in React + Three.js codebases.

Tech Stack

  • Framework: React 18, TypeScript 5 (strict mode, noUnusedLocals, noImplicitAny)
  • 3D: Three.js (WebGL 2), GLB assets with PBR texture sets
  • Animation: GSAP
  • Build: Vite 7 with manual vendor chunking
  • Styling: Sass (SCSS modules) with a token-based variable system
  • Quality: ESLint (flat config), Stylelint (recess-order), Husky pre-commit hook running lint + a full type-checked build
  • CI/CD: GitHub Actions → GitHub Pages

Getting Started

Requirements: Node.js 20+ and a WebGL 2-capable browser.

# 1. Clone
git clone https://github.com/moizahmad418/threejs-react-soft-configurator.git
cd threejs-react-soft-configurator

# 2. Install
npm install --legacy-peer-deps

# 3. Run
npm run dev          # → http://localhost:3000

Available Scripts

Command Description
npm run dev Vite dev server with HMR on port 3000
npm run build Type-checks with tsc, then produces an optimised, vendor-split bundle in dist/
npm run preview Serves the production build locally on port 4173
npm run lint Lints TypeScript and SCSS
npm run lint:fix Auto-fixes lint and style violations

Deployment

This repository deploys itself to GitHub Pages on every push to main. Nothing in the configuration is tied to the repository name.

One-time setup:

  1. Push the project to any GitHub repository.
  2. Open Settings → Pages → Build and deployment.
  3. Set Source to GitHub Actions.

Performance Notes

  • Three.js, GSAP and application code are emitted as separate chunks so vendor bundles cache independently of app releases.
  • The engine and the configurator panel are dynamically imported, keeping WebGL off the critical path for first contentful paint.
  • The GLB model is preloaded via <link rel="preload" as="fetch"> so the network fetch overlaps with JavaScript parsing.
  • Textures are cached and reused across material swaps rather than re-decoded per interaction.
  • Source maps are disabled in production; the chunk-size budget is enforced at 800 kB.

Connect

Portfolio GitHub

Topics · threejs · webgl · 3d-configurator · product-configurator · react · typescript · vite · gsap · pbr · frontend-engineering · creative-coding · 3d-visualization · github-pages

About

A real-time, photorealistic 3D sofa configurator running entirely in the browser. Built with React 18, TypeScript, Three.js and GSAP — no game engine, no server, no paid 3D service.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages