"Creates simple Three.js web apps with scene setup, lighting, geometries, materials, animations, and responsive rendering. Use for 'Create a threejs scene/app/showcase' or when user wants 3D web content. Supports ES modules, modern Three.js r170+ APIs."
Resources
1Install
npx skillscat add shiqkuangsan/oh-my-daily-skills/tooyoung-threejs-builder Install via the SkillsCat registry.
This skill generates basic Three.js web applications with scene configuration, lighting, geometries, materials, animations, and responsive rendering using modern ES module patterns. It addresses the need for quickly creating 3D web content without manually setting up boilerplate code. Developers should use it when they want to create simple Three.js scenes, apps, or showcases with current Three.js APIs.
Three.js Builder
A focused skill for creating simple, performant Three.js web applications using modern ES module patterns.
Quick Start: Minimal Template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Three.js App</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
overflow: hidden;
background: #000;
}
canvas {
display: block;
}
</style>
</head>
<body>
<script type="module">
import * as THREE from "https://unpkg.com/three@0.170.0/build/three.module.js";
// Scene setup
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000,
);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
document.body.appendChild(renderer.domElement);
// Your 3D content here
camera.position.z = 5;
// Animation loop
renderer.setAnimationLoop((time) => {
renderer.render(scene, camera);
});
// Handle resize
window.addEventListener("resize", () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
</script>
</body>
</html>Geometries
Common primitives:
BoxGeometry(width, height, depth)- cubes, boxesSphereGeometry(radius, widthSegments, heightSegments)- balls, planetsCylinderGeometry(radiusTop, radiusBottom, height)- tubes, cylindersTorusGeometry(radius, tube)- donuts, ringsPlaneGeometry(width, height)- floors, wallsIcosahedronGeometry(radius, detail)- low-poly spheres (detail=0)
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({ color: 0x44aa88 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);Materials
MeshBasicMaterial- No lighting, flat colorsMeshStandardMaterial- PBR lighting (default choice)MeshPhongMaterial- Legacy, faster than Standard
Common properties:
{
color: 0x44aa88,
roughness: 0.5, // 0=glossy, 1=matte
metalness: 0.0, // 0=non-metal, 1=metal
wireframe: false,
transparent: false,
opacity: 1.0
}Lighting
No light = black screen (except BasicMaterial).
// Ambient (base illumination)
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambientLight);
// Directional (sun-like)
const mainLight = new THREE.DirectionalLight(0xffffff, 1);
mainLight.position.set(5, 10, 7);
scene.add(mainLight);Animation
// Continuous rotation
renderer.setAnimationLoop((time) => {
mesh.rotation.x = time * 0.001;
mesh.rotation.y = time * 0.0005;
renderer.render(scene, camera);
});
// Wave motion
mesh.position.y = Math.sin(time * 0.002) * 0.5;Camera Controls (OrbitControls)
import { OrbitControls } from "https://unpkg.com/three@0.170.0/examples/jsm/controls/OrbitControls.js";
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
renderer.setAnimationLoop(() => {
controls.update();
renderer.render(scene, camera);
});Common Patterns
Rotating Cube
const cube = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshStandardMaterial({ color: 0x00ff88 }),
);
scene.add(cube);
renderer.setAnimationLoop((time) => {
cube.rotation.x = cube.rotation.y = time * 0.001;
renderer.render(scene, camera);
});Particle Field
const positions = new Float32Array(1000 * 3);
for (let i = 0; i < 1000 * 3; i++) {
positions[i] = (Math.random() - 0.5) * 50;
}
const geometry = new THREE.BufferGeometry();
geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3));
const particles = new THREE.Points(
geometry,
new THREE.PointsMaterial({ size: 0.1 }),
);
scene.add(particles);Colors
Hex format: 0xRRGGBB
- Black:
0x000000, White:0xffffff - Red:
0xff0000, Green:0x00ff00, Blue:0x0000ff - Orange:
0xff8800, Purple:0x8800ff
Key Anti-Patterns
- Creating geometry in animation loop - Memory leak, use once and transform
- Missing
scene.add()- Object won't render - No pixelRatio cap - Use
Math.min(window.devicePixelRatio, 2)
References
references/mobile-touch.md- Touch events, mobile optimizationreferences/advanced-topics.md- GLTF loading, shaders, post-processing
Version Note: Three.js r170 (January 2025). Check threejs.org for updates.