Three.js or Babylon.js

When to Reach for Three.js or Babylon.js Instead

For a general 3D scene (a product viewer, a virtual store, a visualization with models, lights, shadows and post-processing), a full engine saves the most work, and both keep a WebGL 2 path beside WebGPU. Three.js 30,815 (Three.js) is a lean rendering library with the largest ecosystem of examples and add-ons. Babylon.js 89,603 (Babylon.js) is a complete engine with physics, GUI, audio, an inspector and WebXR built in. This chapter carries over: their cameras are MVP Matrices's matrices, their materials Directional and Point Lighting to Normal Maps and PBR's shaders, and both accept custom GLSL. BookNest's bookshelf moves to Three.js in Three.js and its virtual store to Babylon.js in Babylon.js.

The same shadowed shelf of books in Three.js (left) and Babylon.js (right), each a few lines of scene code instead of hundreds of raw WebGL callsHTMLLive
<!doctype html>
<style>
  body { margin: 0; font: 11px system-ui, sans-serif; background: #f7f4ee; color: #333; }
  .row { display: flex; gap: 6px; max-width: 600px; padding: 0 4px; box-sizing: border-box; }
  .row div { flex: 1; min-width: 0; }
  canvas { display: block; width: 100%; height: 240px; }
  p { margin: 3px 0; font: 11px monospace; }
</style>
<div class="row">
  <div><canvas id="three"></canvas><p id="pt">Three.js</p></div>
  <div><canvas id="babylon"></canvas><p id="pb">Babylon.js</p></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/babylonjs@9.28.0/babylon.js"></script>
<script type="module">
import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.186.1/build/three.module.js';
const colors = ['#1e5f8c', '#5b3f99', '#e09a10', '#3f7d3a', '#b5452e', '#2a9d8f'];
// Three.js: renderer, scene, camera, lights, meshes. Its WebGLRenderer draws through WebGL 2.
{
  const canvas = document.getElementById('three');
  const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
  renderer.setSize(canvas.clientWidth, 240, false); renderer.shadowMap.enabled = true;
  const scene = new THREE.Scene(); scene.background = new THREE.Color('#ece8e0');
  const camera = new THREE.PerspectiveCamera(35, canvas.clientWidth / 240, 0.1, 50);
  camera.position.set(1.5, 2.2, 5.8); camera.lookAt(0, 0.4, 0);
  scene.add(new THREE.HemisphereLight('#ffffff', '#8a7a66', 1.4));
  const sun = new THREE.DirectionalLight('#ffffff', 2.2); sun.position.set(3, 5, 4); sun.castShadow = true; scene.add(sun);
  const shelf = new THREE.Mesh(new THREE.BoxGeometry(4, 0.1, 1.2), new THREE.MeshStandardMaterial({ color: '#8a6040' }));
  shelf.position.y = -0.05; shelf.receiveShadow = true; scene.add(shelf);
  colors.forEach((color, i) => {
    const book = new THREE.Mesh(new THREE.BoxGeometry(0.4, 1.1, 0.8), new THREE.MeshStandardMaterial({ color, roughness: 0.6 }));
    book.position.set(-1.5 + i * 0.6, 0.55, 0); book.castShadow = book.receiveShadow = true; scene.add(book);
  });
  renderer.render(scene, camera);
  document.getElementById('pt').textContent = `Three.js r${THREE.REVISION} | WebGL ${renderer.capabilities.isWebGL2 !== false ? 2 : 1}`;
}
// Babylon.js: engine, scene, camera, lights, meshes, shadow generator.
{
  const canvas = document.getElementById('babylon');
  const engine = new BABYLON.Engine(canvas, true);
  const scene = new BABYLON.Scene(engine);
  scene.clearColor = BABYLON.Color4.FromHexString('#ece8e0ff');
  const camera = new BABYLON.ArcRotateCamera('camera', -Math.PI / 2 + 0.25, 1.2, 6.2, new BABYLON.Vector3(0, 0.4, 0), scene);
  camera.fov = 35 * Math.PI / 180; camera.attachControl(canvas, true);
  new BABYLON.HemisphericLight('sky', new BABYLON.Vector3(0, 1, 0), scene).intensity = 0.7;
  const sun = new BABYLON.DirectionalLight('sun', new BABYLON.Vector3(-3, -5, 4), scene); sun.position.set(3, 5, -4);
  const shadows = new BABYLON.ShadowGenerator(1024, sun); shadows.usePercentageCloserFiltering = true;
  const shelf = BABYLON.MeshBuilder.CreateBox('shelf', { width: 4, height: 0.1, depth: 1.2 }, scene);
  shelf.position.y = -0.05; shelf.receiveShadows = true;
  const wood = new BABYLON.StandardMaterial('wood', scene); wood.diffuseColor = BABYLON.Color3.FromHexString('#8a6040'); shelf.material = wood;
  colors.forEach((color, i) => {
    const book = BABYLON.MeshBuilder.CreateBox('book' + i, { width: 0.4, height: 1.1, depth: 0.8 }, scene);
    book.position.set(-1.5 + i * 0.6, 0.55, 0); book.receiveShadows = true;
    const material = new BABYLON.StandardMaterial('m' + i, scene);
    material.diffuseColor = BABYLON.Color3.FromHexString(color); material.specularColor.set(0.15, 0.15, 0.15);
    book.material = material; shadows.addShadowCaster(book);
  });
  engine.runRenderLoop(() => scene.render());
  document.getElementById('pb').textContent = `Babylon.js ${BABYLON.Engine.Version} | WebGL ${engine.webGLVersion}`;
}
</script>