threejs · mengto — Claude Code skill: build Three.js 3D scenes
Guides your agent through building and debugging interactive Three.js scenes: scene, camera, lights, glTF loading, controls and performance.
npx skills add MengTo/Skills --skill threejs -a claude-codeWhat threejs does
The skill kicks in when a page needs real 3D rather than background effects: a spinning product, an interactive hero scene, shader work, 3D data viz. It keeps the agent on the core Three.js model — Scene, Camera, WebGLRenderer, a Mesh built from geometry plus material, lights when the material is not unlit — and the render loop driven by requestAnimationFrame.
Recipes are included. The minimal spinning cube sets up a renderer with antialias and alpha, a perspective camera, MeshStandardMaterial, an AmbientLight and a DirectionalLight, plus a resize handler using setPixelRatio(Math.min(window.devicePixelRatio, 2)) and updateProjectionMatrix(). A separate note tells the agent to honour prefers-reduced-motion: reduce and draw a still frame instead of running the loop.
Resource leaks get their own section. In a single-page app you call geometry.dispose(), material.dispose(), texture.dispose() and renderer.dispose() after a route change, remove listeners and cancel the RAF. Skip that and the tab crashes. The skill also warns against a high pixel ratio on phones and against oversized textures, since both slow the first paint. Before writing code the agent asks whether the scene is decorative or a functional viewer, which devices matter, and what asset formats and file-size limits you have.
What it helps with
- stand up an interactive 3D scene without digging through the docs
- fix stretched rendering after a window resize
- track down leaked WebGL resources across route changes in an SPA
- load a glTF model and wire up OrbitControls
- stay inside a performance budget on mobile GPUs
Example prompts for the agent
- Build a spinning cube with Three.js in canvas #c, with resize handling and prefers-reduced-motion
- Load the model with GLTFLoader, add OrbitControls, and dispose everything on unmount
- Why does the tab crash after a route change? Check dispose on geometries, materials and the renderer
How to install threejs
1Skills CLI (Vercel)
npx skills add MengTo/Skills --skill threejs -a claude-code2Manually: put the files in place
~/.claude/skills/threejs/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/threejs/
1Skills CLI (Vercel)
npx skills add MengTo/Skills --skill threejs -a codex2Manually: put the files in place
.agents/skills/threejs/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add MengTo/Skills --skill threejs -a cursor2Manually: put the files in place
.cursor/skills/threejs/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install MengTo/Skills threejs2Manually: put the files in place
.github/skills/threejs/SKILL.md1Skills CLI (Vercel)
npx skills add MengTo/Skills --skill threejs -a gemini-cli2Platform CLI
gemini skills install https://github.com/MengTo/Skills --path agent-skills/web-design/threejsManually: put the files in place
.devin/skills/threejs/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add MengTo/Skills --skill threejs -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about threejs
How do I install threejs in Claude?
Run npx skills add MengTo/Skills --skill threejs -a claude-code. The skill lands in ~/.claude/skills/threejs/SKILL.md.
What does the threejs skill do?
It tells the agent how to build and debug Three.js scenes: scene, camera, renderer, lights and materials, glTF loading, controls, and cleanup of WebGL resources.
Which platforms support the threejs skill?
Claude, Codex, Cursor, GitHub Copilot, Gemini CLI and OpenCode. Each has its own install line, for example npx skills add MengTo/Skills --skill threejs -a cursor.
Source text
SKILL.md · MIT
---
name: threejs
description: Use when building or debugging interactive 3D scenes on the web with Three.js (scene/camera/renderer, lights/materials, GLTF loading, controls, performance). Helpful for designers shipping 3D UI moments.
---
# Three.js — WebGL 3D Scenes Skill
## When to use
- Real 3D: product spins, interactive hero scenes, shaders/material effects, 3D data viz
- You need full control beyond “background effects”
- You can budget time for asset pipeline + performance tuning
## Core mental model
- Create:
- `Scene` (root graph)
- `Camera` (Perspective/Orthographic)
- `Renderer` (`WebGLRenderer`)
- `Mesh` = `Geometry` + `Material`
- Lights (if using non-unlit materials)
- Render loop:
- `requestAnimationFrame(animate)`
- Update time-based animations, controls, mixers, then `renderer.render(scene, camera)`
## Key APIs/patterns
- Setup:
- `const renderer = new THREE.WebGLRenderer({ canvas, antialias, alpha })`
- `renderer.setSize(width, height, false)`
- `renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))`
- Camera:
- `camera.aspect = width / height; camera.updateProjectionMatrix()`
- Scene graph:
- `scene.add(object)` / `object.position/rotation/scale`
- Loading assets:
- `GLTFLoader` (models), `TextureLoader` (images), `DRACOLoader` (compressed glTF)
- Controls (common):
- `OrbitControls` (debug/product), `PointerLockControls` (FPS), custom pointer handlers
- Cleanup (important in SPAs):
- `geometry.dispose()`, `material.dispose()`, `texture.dispose()`, `renderer.dispose()`
- Remove event listeners; cancel RAF.
## Common pitfalls
- Not handling resize → stretched/cropped rendering
- Too high devicePixelRatio → mobile GPU meltdown
- Leaking WebGL resources (not disposing) → crashes after route changes
- Loading huge textures/models → slow start; use compressed textures, Draco/KTX2, smaller maps
- Using too many lights/shadows → expensive; fake lighting with baked textures when possible
## Quick recipes
### 1) Minimal spinning cube
```js
import * as THREE from "three";
const canvas = document.querySelector("#c");
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true });
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, 1, 0.1, 100);
camera.position.set(0, 0, 4);
const geom = new THREE.BoxGeometry(1, 1, 1);
const mat = new THREE.MeshStandardMaterial({ color: 0x7c3aed });
const mesh = new THREE.Mesh(geom, mat);
scene.add(mesh);
scene.add(new THREE.AmbientLight(0xffffff, 0.8));
const dir = new THREE.DirectionalLight(0xffffff, 0.8);
dir.position.set(2, 2, 2);
scene.add(dir);
function resize() {
const w = canvas.clientWidth;
const h = canvas.clientHeight;
renderer.setSize(w, h, false);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
camera.aspect = w / h;
camera.updateProjectionMatrix();
}
window.addEventListener("resize", resize);
resize();
function animate(t) {
mesh.rotation.y = t * 0.0006;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
```
### 2) Respect reduced motion
- If `prefers-reduced-motion: reduce`, render a still frame (no RAF) or slow updates.
## What to ask the user
- Is this decorative (hero) or functional 3D (product viewer)?
- Target devices: mobile? older iPhones?
- Asset format availability (glTF, HDRI, textures) and file size constraints
- Accessibility/reduced motion requirements
© MengTo · MIT · MengTo/Skills
Similar skills
Everything for Frontend and UI →threejs by other authors comes first.