← Back to list
⚡

threejs-scene-setup Checked

Stand up a three.js scene: import maps and the three/addons path, the Scene/PerspectiveCamera/Web…
⚡ Productivity skills By gamedev-skills Version v1.0.0 Added 2026-10-21 Updated 2026-10-21 Source ↗ Part of Game Development →
7.7Overall rating
0Views
0Downloads
2.0kStars

Installation

🤖 Install via AI

Copy the prompt below and send it to your AI assistant (e.g. Claude Code) — it will follow the instructions and install automatically.

Install the "threejs-scene-setup" skill by following the instructions at https://skill123.me/install/threejs-scene-setup.
⌨️ Command line install

Run in your terminal — downloads and installs to ~/.claude/skills/.

curl -fsSL https://skill123.me/install/threejs-scene-setup.sh | bash
📦 Download ZIP

Download the zip and extract it into your skills directory (e.g. ~/.claude/skills/), then restart your session.

⬇ Download v1.0.0 · 5 KB
📊 Static rating
7.7/10
Trigger
8.0
Structure
0.0
Workflow
8.0
Content
0.0
Engineering
0.0
Security
7.0

Six-dimension rubric with reviewer rationale.

View scorecard ↓
🛡 Dynamic test
—

Not live-tested yet — this skill is rated on static analysis only.

About this skill

Stand up a three.js scene: import maps and the three/addons path, the Scene/PerspectiveCamera/WebGLRenderer trio, the setAnimationLoop render loop, responsive resize, and OrbitControls. Use when starting or debugging a three.js app — when the user mentions three.js, THREE.Scene, WebGLRenderer, PerspectiveCamera, the render loop, resizing, or OrbitControls. For models use threejs-gltf-loading; for materials/lights use threejs-materials-lighting.

three.js Scene Setup

Create the foundation of a three.js app: module loading, the

scene/camera/renderer trio, the render loop, responsive resizing, and camera

controls. Patterns target **r186**. Read the installed three version before

changing an existing project because examples and addons move across releases.

Documentation

Stand up a three.js scene: import maps and the three/addons path, the Scene/PerspectiveCamera/WebGLRenderer trio, the setAnimationLoop render loop, responsive resize, and OrbitControls. Use when starting or debugging a three.js app — when the user mentions three.js, THREE.Scene, WebGLRenderer, PerspectiveCamera, the render loop, resizing, or OrbitControls. For models use threejs-gltf-loading; for materials/lights use threejs-materials-lighting.

three.js Scene Setup

Create the foundation of a three.js app: module loading, the

scene/camera/renderer trio, the render loop, responsive resizing, and camera

controls. Patterns target **r186**. Read the installed three version before

changing an existing project because examples and addons move across releases.

When to use

  • Use when bootstrapping a three.js scene, fixing a blank/black canvas, making the

canvas responsive, setting up the animation loop, or adding OrbitControls.

  • Use when package.json depends on three and code does `import * as THREE from

'three'`.

**When *not* to use:** loading .gltf/.glb models or skinned animation →

threejs-gltf-loading. Materials, lights, shadows, environment maps →

threejs-materials-lighting. 2D rendering → pixijs-rendering.

Core workflow

1. **Load three.js as an ES module with an import map.** Since r147 the bare

specifier 'three' and 'three/addons/' must be mapped (in HTML or by a

bundler). Addons (controls, loaders) live under three/addons/....

2. **Create the trio.** A Scene (root of the graph), a `PerspectiveCamera(fov,

aspect, near, far) moved back from the origin, and a WebGLRenderer` whose

domElement is in the DOM. Set size and pixelRatio.

3. **Add a mesh.** new Mesh(geometry, material) and scene.add(mesh). With a

lit material you also need a light (see threejs-materials-lighting).

4. **Drive a render loop with renderer.setAnimationLoop(fn).** It's the modern,

WebXR-/WebGPU-safe replacement for hand-rolled requestAnimationFrame. Use a

Timer for delta time (Clock is deprecated since r183).

5. **Handle resize** so the camera aspect and renderer match the canvas; update

camera.aspect, call updateProjectionMatrix(), and renderer.setSize(...).

6. **Add OrbitControls** for orbit/pan/zoom while developing. Confirm something

actually renders (a lit cube, the controls responding) before assuming success.

Patterns

### 1. HTML import map + module entry (no bundler)


<canvas id="c"></canvas>
<script type="importmap">
{
  "imports": {
    "three": "https://cdn.jsdelivr.net/npm/three@0.186.0/build/three.module.js",
    "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.186.0/examples/jsm/"
  }
}
</script>
<script type="module" src="./main.js"></script>

With a bundler (Vite/webpack), skip the import map and just

npm i three; the same import statements resolve.

### 2. Scene + camera + renderer


// main.js
import * as THREE from 'three';
View full documentation

const canvas = document.querySelector('#c');

const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });

renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); // cap for perf

renderer.setSize(window.innerWidth, window.innerHeight);

const scene = new THREE.Scene();

scene.background = new THREE.Color(0x101018);

const camera = new THREE.PerspectiveCamera(

60, // vertical field of view (degrees)

window.innerWidth / window.innerHeight, // aspect

0.1, // near

100 // far

);

camera.position.set(3, 2, 5);

camera.lookAt(0, 0, 0);

const cube = new THREE.Mesh(

new THREE.BoxGeometry(1, 1, 1),

new THREE.MeshNormalMaterial() // unlit; shows orientation without a light

);

scene.add(cube);



### 3. The render loop (setAnimationLoop + Timer)

const timer = new THREE.Timer(); // replaces the deprecated THREE.Clock (r183+)

timer.connect(document); // optional: no huge delta after a hidden tab

renderer.setAnimationLoop((time) => {

timer.update(time); // call once per frame, before getDelta()

const dt = timer.getDelta(); // seconds since last frame

cube.rotation.x += dt; // frame-rate independent

cube.rotation.y += dt * 0.7;

renderer.render(scene, camera);

});

// renderer.setAnimationLoop(null); // stop the loop



### 4. Responsive resize

function onResize() {

const w = window.innerWidth, h = window.innerHeight;

camera.aspect = w / h;

camera.updateProjectionMatrix(); // required after changing aspect

renderer.setSize(w, h);

}

window.addEventListener('resize', onResize);



### 5. OrbitControls (orbit / pan / zoom)

import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

const controls = new OrbitControls(camera, renderer.domElement);

controls.enableDamping = true; // inertial feel

controls.target.set(0, 0, 0);

renderer.setAnimationLoop(() => {

controls.update(); // needed every frame when damping is on

renderer.render(scene, camera);

});



## Pitfalls

- **`Failed to resolve module specifier "three"`** → missing import map (or bundler
  config). Map both `"three"` and `"three/addons/"`; addon paths must end with `/`.
- **Black canvas, no errors** → camera is at the origin (inside/behind the object),
  or you used a lit material (`MeshStandardMaterial`) with no light. Move the camera
  back; use `MeshNormalMaterial`/`MeshBasicMaterial` to verify geometry first.
- **Nothing animates** → you never called `renderer.render` inside the loop, or you
  call `setAnimationLoop` but render outside it.
- **Stretched / squashed view on resize** → you resized the renderer but didn't
  update `camera.aspect` + `updateProjectionMatrix()`.
- **Blurry or jagged on HiDPI** → set `renderer.setPixelRatio(...)`; cap it (≈2) so
  4K/retina screens don't tank performance.
- **OrbitControls feel dead** → with `enableDamping = true` you must call
  `controls.update()` every frame.
- **Old tutorials use `<script src="three.min.js">`** → since r147 three.js ships
  ES modules only; use `type="module"` + import maps.

## References

- For coordinate conventions, the scene-graph (`Group`, parent/child transforms,
  `Object3D` add/remove), `OrthographicCamera` for 2.5D, and disposing of
  geometries/materials/textures to avoid leaks, read `references/scene-graph.md`.

## Related skills

- `threejs-materials-lighting` — give surfaces a lit look (lights, shadows, PBR).
- `threejs-gltf-loading` — load 3D models and play their animations.
- `pixijs-rendering` — 2D rendering in the browser.
- `fps-shooter` — a 3D genre template that composes three.js skills.

Score breakdown

Trigger
8.0
Structure
0.0
Workflow
8.0
Content
0.0
Engineering
0.0
Security
7.0