three-js

Three.js Best Practices

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "three-js" with this command: npx skills add 5dlabs/cto/5dlabs-cto-three-js

Three.js Best Practices

Comprehensive performance optimization guide for Three.js applications with 100+ rules across 17 categories.

When to Apply

Reference these guidelines when:

  • Setting up a new Three.js project

  • Writing or reviewing Three.js code

  • Optimizing performance or fixing memory leaks

  • Working with custom shaders (GLSL or TSL)

  • Implementing WebGPU features

  • Building VR/AR experiences with WebXR

Rule Categories by Priority

Priority Category Impact Prefix

0 Modern Setup & Imports FUNDAMENTAL setup-

1 Memory Management & Dispose CRITICAL memory-

2 Render Loop Optimization CRITICAL render-

3 Geometry & Buffer Management HIGH geometry-

4 Material & Texture Optimization HIGH material-

5 Lighting & Shadows MEDIUM-HIGH lighting-

6 Scene Graph Organization MEDIUM scene-

7-8 Shader Best Practices MEDIUM shader- , tsl-

9-17 Loading, Camera, Animation, Physics, WebXR, Audio, Mobile, Production, Debug VARIES

Quick Reference

Modern Import Maps

<script type="importmap"> { "imports": { "three": "https://cdn.jsdelivr.net/npm/three@0.182.0/build/three.module.js", "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.182.0/examples/jsm/", "three/tsl": "https://cdn.jsdelivr.net/npm/three@0.182.0/build/three.tsl.js" } } </script>

Memory Management (CRITICAL)

Always dispose resources:

function disposeObject(obj) { if (obj.geometry) obj.geometry.dispose(); if (obj.material) { if (Array.isArray(obj.material)) { obj.material.forEach(m => m.dispose()); } else { obj.material.dispose(); } } }

// Recursive disposal for hierarchies function disposeHierarchy(obj) { obj.traverse(child => disposeObject(child)); }

Render Loop (CRITICAL)

// Use setAnimationLoop, not manual RAF renderer.setAnimationLoop(animate);

// Never allocate in render loop const _tempVector = new THREE.Vector3(); // Reuse outside loop

function animate(time) { // Use cached objects _tempVector.set(0, 1, 0);

// Use delta time for animations const delta = clock.getDelta(); mixer.update(delta);

renderer.render(scene, camera); }

Geometry (HIGH)

// Use InstancedMesh for identical objects const mesh = new THREE.InstancedMesh(geometry, material, count); const matrix = new THREE.Matrix4();

for (let i = 0; i < count; i++) { matrix.setPosition(positions[i]); mesh.setMatrixAt(i, matrix); } mesh.instanceMatrix.needsUpdate = true;

Materials & Textures (HIGH)

// Reuse materials const sharedMaterial = new THREE.MeshStandardMaterial({ color: 0xff0000 });

// Use compressed textures const ktx2Loader = new KTX2Loader() .setTranscoderPath('path/to/basis/') .detectSupport(renderer);

// Power-of-two texture dimensions // 512x512, 1024x1024, 2048x2048

Mobile Optimization

const isMobile = /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);

// Limit pixel ratio renderer.setPixelRatio(Math.min(window.devicePixelRatio, isMobile ? 1.5 : 2));

// Reduce shadow map size on mobile if (isMobile) { light.shadow.mapSize.width = 512; light.shadow.mapSize.height = 512; }

TSL (Three.js Shading Language)

import { texture, uv, color, time, sin } from 'three/tsl';

const material = new THREE.MeshStandardNodeMaterial(); material.colorNode = texture(map).mul(color(0xff0000)); material.colorNode = color(0x00ff00).mul(sin(time).mul(0.5).add(0.5));

Key Patterns

Pattern Benefit

Use InstancedMesh 100x draw calls → 1 draw call

Merge static geometries Reduce draw calls

Use LOD (Level of Detail) Performance at distance

Enable frustum culling Skip off-screen objects

Use texture atlases Reduce material switches

Bake lighting Eliminate runtime shadows

Anti-Patterns

Anti-Pattern Fix

Creating objects in render loop Cache and reuse

Not disposing resources Always call .dispose()

Using BufferGeometry constructor Use specific geometry classes

Too many lights Limit to 3-4 dynamic lights

High pixel ratio on mobile Cap at 1.5-2

Attribution

Based on emalorenzo/three-agent-skills three-best-practices - 53+ installs. Official guidelines from Three.js llms branch maintained by mrdoob.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

expo-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

better-auth-expo

No summary provided by upstream source.

Repository SourceNeeds Review
General

elysia-llm-docs

No summary provided by upstream source.

Repository SourceNeeds Review
General

frontend-excellence

No summary provided by upstream source.

Repository SourceNeeds Review