Three.js and WebGL: a complete overview of 3D on websites

What WebGL and Three.js are, when 3D on a site pays off and when it only adds weight: 8 areas, pros and cons, a comparison with Babylon.js, Spline and video, speed rules, WebGPU and code examples.

Stack and technologies Updated

In short

WebGL is the browser’s interface to the graphics card, and Three.js is the most popular free library on top of it: it turns low-level graphics calls into a scene with a camera, lights, materials and models. Together they put real 3D on a page without plugins — product viewers and configurators, hero scenes, data visualisation, games and AR. The newer WebGPU standard is supported by Three.js too, and browser support for it keeps growing. The price of 3D is weight and battery: models must be compressed, scenes paused when off screen, weak devices and visitors who switched motion off get a lighter version.

Three.js and WebGL at a glance

The main facts about the standard and the library in one table.

WebGL
A Khronos Group standard: the browser’s access to the GPU; WebGL 2 is supported everywhere
WebGPU
The new generation: closer to modern graphics APIs, with computations on the GPU; support is growing
Three.js
A 3D library by Ricardo Cabello (mrdoob), 2010; MIT licence
What it gives
Scenes, cameras, lights, physically based materials, model loaders, post-processing
Renderers
WebGLRenderer and WebGPURenderer with automatic fallback to WebGL
Model format
glTF — “the JPEG of 3D”; compression with Draco or Meshopt, textures in KTX2
Releases
Roughly monthly, numbered by revision (r186 at the time of writing)
With React
React Three Fiber and drei — scenes as components
Alternatives
Babylon.js, PlayCanvas; for scenes without code — Spline
Models are made in
Blender and other 3D editors, then exported to glTF

What Three.js is used for: 8 areas

3D earns its weight where it shows what a picture cannot.

  1. 01

    Product in 3D

    Turn, zoom and see from every side — before buying.

    glTFOrbitControls

  2. 02

    Configurators

    Colour, material, size — the model changes in real time.

    furniturecars

  3. 03

    Hero scenes

    Launches and premium brands that need to be remembered.

    shadersscroll

  4. 04

    Data visualisation

    Thousands of points, globes and networks that 2D cannot hold.

    InstancedMesh

  5. 05

    Real estate and interiors

    Walking through a flat or an office before it is built.

    tours

  6. 06

    Games and promo

    Small games in the browser without installation.

    physics

  7. 07

    AR and VR

    WebXR puts the model into the room through the phone camera.

    WebXR

  8. 08

    Interfaces with depth

    Light 3D accents in an interface where they help understanding.

    React Three Fiber

Pros and cons of Three.js

Three.js makes 3D accessible, but it does not make it free: every scene costs bytes and battery.

Pros · 8

  • Real 3D without plugins

    Works in every modern browser on phones and computers.

  • A friendly level of abstraction

    A scene, a camera and a mesh instead of hundreds of lines of raw graphics code.

  • Huge community

    Thousands of examples, answers and ready effects.

  • glTF and good loaders

    Models from Blender arrive with materials and animations.

  • Physically based materials

    Metal, wood and glass look believable under any light.

  • Ready for WebGPU

    The same scene can render through WebGPU and fall back to WebGL.

  • Works with React

    React Three Fiber turns scenes into components.

  • Free

    MIT licence, no royalties for commercial use.

Cons · 8

  • Weight

    The library plus models and textures — megabytes if not compressed.

  • Battery and heat

    A scene drawn 60 times a second works the GPU constantly.

  • Weak devices

    Old phones stutter on heavy effects — a lighter version is needed.

  • Invisible to search

    What is drawn on a canvas is not text: the content must be in the HTML too.

  • A frequently changing API

    Monthly releases sometimes rename and remove things — upgrades need care.

  • Needs 3D skills

    Good scenes need modelling, light and shaders, not only code.

  • Accessibility

    Screen readers do not see a canvas; keyboard control is written by hand.

  • Not a game engine

    Physics, editor and game logic come from other tools.

Three.js compared with Babylon.js, PlayCanvas, Spline and video

Ways to put 3D on a page, from code to a pre-rendered clip.

CriterionThree.jsBabylon.jsPlayCanvasSplineVideo
What it is a 3D library a 3D engine an engine with an editor a design tool a pre-rendered clip
Interactivity full full full basic none
Flexibility the highest high high within the tool none
Weight medium larger medium medium depends on the file
Who builds it a developer a developer a developer with an editor a designer a 3D artist
Best for custom scenes and product viewers complex 3D apps and games browser games and ads quick decorative 3D complex scenes without interaction

When 3D on Three.js is worth it — and when not

Ten typical tasks with a verdict.

  • Viewing a product from every side

    Best fit

    3D shows what photos cannot.

  • Configurator

    Best fit

    Combinations change in real time instead of hundreds of renders.

  • Launch of a premium brand

    Best fit

    A memorable first screen is worth its weight.

  • Visualisation of large data

    Best fit

    Thousands of objects are drawn by the GPU.

  • Background decoration

    Works

    Often a video or CSS gives the same effect lighter.

  • A complex scene without interaction

    Works

    A compressed video may be cheaper for the device.

  • A full game

    Works

    Possible, but an engine like Babylon.js or PlayCanvas gives more out of the box.

  • A corporate site “to look modern”

    Pick another

    3D without a task adds weight and distracts.

  • An audience on weak phones

    Pick another

    Photos and a little motion work better.

  • Content that must be found in search

    Pick another

    Text belongs in the HTML, not on a canvas.

How to keep 3D fast: 8 rules

  1. 01

    Compress models

    Draco or Meshopt make glTF several times smaller.

  2. 02

    Textures in KTX2

    They stay compressed even in the GPU memory.

  3. 03

    Limit the pixel ratio

    Above 2x the eye sees no difference, and the GPU draws twice as much.

  4. 04

    Draw only when visible

    A scene off screen stops — the battery says thank you.

  5. 05

    Load on demand

    The library and the model load when the visitor reaches the block.

  6. 06

    Fewer draw calls

    Thousands of identical objects are drawn as one with InstancedMesh.

  7. 07

    A picture first

    A still image stands in place of the scene until it is ready — and for weak devices instead of it.

  8. 08

    Respect reduced motion

    If motion is switched off in the system, show one still frame.

The Three.js ecosystem: tools for common tasks

The library draws; models, compression and effects come from around it.

TaskTools
Modelling Blender
Compressing glTF gltf-transform, Draco, Meshopt
Textures KTX2, Basis Universal
Scenes in React React Three Fiber, drei
Post-processing postprocessing, EffectComposer
Physics Rapier, cannon-es
Animation timeline Theatre.js
Debugging lil-gui, Spector.js
AR and VR WebXR

Common mistakes with 3D on sites

  1. A model straight from the editor

    Tens of megabytes of uncompressed geometry and textures — the visitor leaves before it loads.

  2. Endless rendering

    A scene that draws even when nobody sees it heats the phone for nothing.

  3. Text inside the scene

    Neither search engines nor screen readers see it.

  4. No fallback

    If WebGL fails, the visitor sees an empty rectangle.

  5. Forgotten resources

    Geometries and textures that are not disposed eat GPU memory with every page change.

  6. 3D for the sake of 3D

    If the scene does not explain or sell, it only adds weight.

What Three.js looks like: 3 examples

A minimal scene, a product viewer and drawing only while visible. Checked by TypeScript 7 with Three.js r186; the first and third run in Chromium.

A minimal scene

A rotating cube with light, a correct size on resize and a capped pixel ratio.

scene.ts
import * as THREE from 'three';

// a scene, a camera and a renderer: the three things every 3D page starts with
const canvas = document.querySelector<HTMLCanvasElement>('#scene')!;
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); // above 2x the eye sees no difference, the GPU does

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, 1, 0.1, 100);
camera.position.set(0, 1.2, 4);

const cube = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  new THREE.MeshStandardMaterial({ color: 0xe4ff4e, roughness: 0.4 }),
);
scene.add(cube, new THREE.HemisphereLight(0xffffff, 0x222222, 2.5));

function resize() {
  const { clientWidth: w, clientHeight: h } = canvas;
  renderer.setSize(w, h, false);
  camera.aspect = w / h;
  camera.updateProjectionMatrix();
}
window.addEventListener('resize', resize);
resize();

renderer.setAnimationLoop((time) => {
  cube.rotation.y = time / 1000;
  renderer.render(scene, camera);
});

A product viewer

A compressed glTF model that the visitor turns and zooms within set limits.

product.ts
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

// a product viewer: a compressed glTF model that the visitor can turn and zoom
export async function showProduct(canvas: HTMLCanvasElement, url: string) {
  const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true });
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
  renderer.setSize(canvas.clientWidth, canvas.clientHeight, false);

  const scene = new THREE.Scene();
  scene.add(new THREE.HemisphereLight(0xffffff, 0x444444, 3));
  const camera = new THREE.PerspectiveCamera(35, canvas.clientWidth / canvas.clientHeight, 0.1, 50);
  camera.position.set(0, 0.6, 2.4);

  const draco = new DRACOLoader().setDecoderPath('/draco/'); // the model is compressed several times over
  const gltf = await new GLTFLoader().setDRACOLoader(draco).loadAsync(url);
  scene.add(gltf.scene);

  const controls = new OrbitControls(camera, canvas);
  controls.enableDamping = true;
  controls.minDistance = 1;
  controls.maxDistance = 4;

  renderer.setAnimationLoop(() => {
    controls.update();
    renderer.render(scene, camera);
  });
  return renderer;
}

Draw only while visible

Off screen the scene stops; with motion switched off — one still frame.

visibility.ts
import type { WebGLRenderer } from 'three';

// a 3D scene should not drain the battery: draw only while it is visible
export function renderOnlyWhenVisible(
  renderer: WebGLRenderer,
  canvas: HTMLCanvasElement,
  draw: (time: number) => void,
) {
  const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  if (reduced) {
    draw(0); // motion is switched off in the system: one still frame
    return;
  }
  new IntersectionObserver(([entry]) => {
    renderer.setAnimationLoop(entry?.isIntersecting ? draw : null);
  }).observe(canvas);
}

Questions about Three.js and WebGL

What is the difference between WebGL and Three.js?

WebGL is the browser’s low-level access to the GPU; Three.js is a library that turns it into scenes, cameras and models.

Will 3D work on phones?

Yes, if the scene is light: compressed models, a capped pixel ratio and a still version for weak devices.

Does 3D hurt SEO?

Not if the content stays in the HTML and the scene loads lazily without slowing the first screen.

Where do 3D models come from?

They are made in Blender or another editor, or prepared from the manufacturer’s CAD files, then exported to glTF and compressed.

What is WebGPU and do I need it?

The next-generation graphics standard. Three.js can use it with a fallback to WebGL, so a site works on any browser.

Three.js or Spline?

Spline is quick for decorative 3D made by a designer; Three.js gives full control over weight, interaction and logic.

Can Three.js be used with React?

Yes, through React Three Fiber: the scene is described with components.

Is a video better than 3D?

If there is no interaction — often yes. 3D wins when the visitor needs to turn, choose or explore.

Online form

3D for
your site

I build 3D scenes on Three.js where they are justified: product viewers, configurators and hero scenes — compressed models, a speed budget and a light version for weak devices. Tell me about the idea — I answer within one working day.

Or write to [email protected]