Get Started
Get a Three.js scene rendering in five minutes. npm install, set up a renderer, scene, camera, mesh, and animation loop.
Three.js — getting started
EXAMPLE
# ===== 1. Install =====
npm install three
# TypeScript: npm install -D @types/three
# ===== 2. The smallest scene (Vite + TS) =====
// src/main.ts
import * as THREE from 'three';
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x202428);
const camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 0.1, 1000);
camera.position.set(3, 3, 5);
camera.lookAt(0, 0, 0);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(innerWidth, innerHeight);
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
document.body.appendChild(renderer.domElement);
const cube = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshStandardMaterial({ color: 0x4488ff })
);
scene.add(cube);
scene.add(new THREE.AmbientLight(0xffffff, 0.4));
const dir = new THREE.DirectionalLight(0xffffff, 1);
dir.position.set(5, 5, 5);
scene.add(dir);
renderer.setAnimationLoop(() => {
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
});
addEventListener('resize', () => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
});
# ===== 3. Add interactive camera =====
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
# In the loop: controls.update();
# ===== 4. Load a glTF model =====
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
const loader = new GLTFLoader();
loader.load('/model.glb', (gltf) => {
scene.add(gltf.scene);
});
# ===== 5. React wrapper (optional) =====
npm install three @react-three/fiber @react-three/drei
# Lets you declare scenes in JSX, with React state.
# ===== Patterns to internalise =====
# - One renderer, attached once
# - Use setAnimationLoop, not setInterval / requestAnimationFrame manual recursion
# - Handle resize for camera + renderer
# - Dispose geometries / materials / textures on cleanup
# - Pixel ratio capped (devicePixelRatio can be 3+ on phones; expensive)
# ===== Pitfalls =====
# - Not resizing on window change -> stretched view
# - Antialiasing on integrated GPUs at high DPR -> heavy
# - Loading raw models (no draco compression) -> large bundles
# - Forgetting controls.update() with damping enabled
Why it matters
A scene + camera + renderer + mesh + a light + a loop is all it takes. Add OrbitControls for navigation, the glTF loader for assets, and resize handling. From there the journey is up to you — shaders, post-processing, physics, VR all build on this same skeleton.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
npm install three // or via CDN import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.165/build/three.module.js';Try it Yourself »
Discussion
Loading…