4
integrations
6
documented sections
Overview
Three.js renders 3D graphics in the browser, wrapping the verbose WebGL API in concepts a developer can hold in their head: scenes, cameras, geometries, materials, lights. It is the most established option for browser 3D, behind product configurators, data visualizations, games, and interactive art across the web.
The library ships in numbered revisions rather than semantic versions, and r184 is a landmark: the WebGPU renderer is production-ready alongside WebGL, the biggest architectural change in years, opening richer real-time graphics on modern hardware.
The Scene Graph
A 3D scene is organized like a family tree: every object can have children, and children move with their parents. A mesh, the most common visible object, pairs a geometry that defines shape with a material that defines surface, while a camera sets the viewpoint and lights make materials respond. Grouped motion falls out of the structure naturally; rotate a parent and everything attached rotates with it, which keeps complex scene animation manageable.
import * as THREE from 'three'
const scene = new THREE.Scene()
const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshStandardMaterial({ color: 0xf5c400 })
const cube = new THREE.Mesh(geometry, material)
scene.add(cube)
scene.add(new THREE.AmbientLight(0xffffff, 0.6))The Render Loop
Like film, real-time 3D is an illusion of stills shown quickly: the render loop draws the scene roughly sixty times per second through requestAnimationFrame. Each frame updates object transforms and renders the scene from the camera, producing continuous motion. Per-frame logic such as rotation, physics, or camera movement belongs inside this loop, never in code that runs once, and the loop must stay lean because everything in it repeats dozens of times every second.
React Three Fiber
React Three Fiber lets a 3D scene be written as React components, where elements like mesh and their geometries and materials map straight onto Three.js equivalents. The useFrame hook runs per-frame logic without leaving the component model, and the Drei helper library supplies ready-made controls, loaders, and abstractions that save days of setup. The 3D code reads like the rest of the codebase, and resource lifecycle is tied to component mounting. One firm rule: per-frame updates go in useFrame, never in the render body.
How Devyst Uses Three.js
We build all 3D through React Three Fiber, with every scene kept in a dedicated three directory, fully separate from interface sections. Per-frame work runs inside useFrame rather than React render, following the rule that animation updates never happen during rendering. Scroll-linked camera and object motion is coordinated with GSAP where precise sequencing matters, and geometries and materials are disposed on unmount so GPU memory is released the moment a scene leaves the page.
Performance and Disposal
Graphics memory does not clean up after itself: geometries, materials, and textures must be disposed explicitly when no longer needed, or GPU memory leaks until the page struggles. Performance also depends on limiting draw calls, reusing geometries and materials, and keeping per-frame work minimal; instanced meshes draw many copies of an object in a single call, and capping the renderer pixel ratio avoids painting more pixels than a display can show. We dispose all scene resources on unmount and profile frame cost before adding visual complexity, so beauty never comes at the price of speed.