A real-time 3D product configurator built with React Three Fiber. Configure a 3D-printed desk lamp — rotate it, change the base, stem, and shade, pick materials, and get a live price — then share your build with a link.
- Live 3D preview — a parametric lamp built from Three.js geometry, with orbit controls (drag to rotate, scroll to zoom) and a toggleable auto-rotate.
- Configure every part — base shape (round/square) and colour, stem finish (matte/metallic), colour and height, shade style (cone/dome/drum) and colour, and warm/cool light.
- Running price — each option adjusts the price in real time.
- Shareable builds — the full configuration is encoded in the URL, so any build can be copied and reopened exactly as designed. There is a "Surprise me" randomiser and a reset.
- Next.js 16 (App Router) — the page is fully static (prerendered), so it deploys anywhere with no backend or secrets.
- @react-three/fiber + @react-three/drei + three.js — the renderer,
OrbitControls,ContactShadows, and a procedural studio environment (Lightformers, so metals reflect properly with no external HDR files). - TypeScript + Tailwind CSS v4.
- All geometry is generated in code — there are no model files or third-party assets to load.
src/
├── lib/lamp-config.ts # option sets, price calc, URL encode/decode, randomiser
├── components/
│ ├── LampModel.tsx # parametric Three.js lamp (base / stem / shade / bulb + light)
│ ├── Scene.tsx # <Canvas>: lights, environment, orbit controls, ground shadow
│ └── Configurator.tsx # control panel + state + URL sync (Scene loaded client-only)
└── app/page.tsx
The 3D Scene is imported with next/dynamic({ ssr: false }) so WebGL never runs during
server rendering, while the configuration is restored from the URL after mount to avoid a
hydration mismatch.
npm install
npm run dev # http://localhost:3000
npm run build # static production buildMIT. See LICENSE.
Built by Perfecto II Cayabyab.
