skills/threejs-r3f/SKILL.md
This skill should be used when the user asks to "build a Three.js scene", "set up React Three Fiber", "animate a mesh with useFrame", "load a GLTF or GLB model", or "add physics with react-three/rapier". Covers scene setup, Drei helpers, the asset pipeline, responsive canvas, and performance budgets for Three.js and React Three Fiber projects.
npx skillsauth add b-open-io/prompts threejs-r3fInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Guide for building 3D web experiences with R3F v9 (React 19) and the pmndrs ecosystem.
| Package | Version | React |
|---------|---------|-------|
| @react-three/fiber | v9.x | 19.x |
| @react-three/drei | v9.x+ | 19.x |
| @react-three/rapier | v2.x | 19.x |
| three | r171+ | — |
Use fiber v8 + rapier v1 for React 18 projects. Never mix version lines.
bun create vite my-scene -- --template react-ts
cd my-scene
bun add three @react-three/fiber @react-three/drei
bun add -d @types/three
bun dev
bun add three @react-three/fiber @react-three/drei
bun add -d @types/three
Optional packages: bun add @react-three/rapier (physics), bun add zustand (state), bun add leva (debug GUI).
For the minimal scene template, Canvas prop table, frameloop values, responsive canvas, and WebGPU renderer bootstrap, read references/scene-setup.md.
Key facts to keep in mind without reading the reference:
Canvas defaults: antialias: true, outputColorSpace = SRGBColorSpace, toneMapping = ACESFilmicToneMapping, ColorManagement.enabled = truedpr={[1, 2]} to clamp device pixel ratioshadows="soft" for shadow maps; add castShadow/receiveShadow to meshesframeloop="demand" for static scenes that only need to re-render on interactionAll import from @react-three/drei. Read references/drei-helpers.md for full inventory, props, and examples.
Controls
OrbitControls — rotate/zoom/pan; add makeDefault to expose via useThreeScrollControls — scroll-driven scenes; pair with useScroll inside useFramePresentationControls — spring-animated drag; no OrbitControls neededKeyboardControls — typed key state context; read imperatively via get() in useFrameStaging
Environment — IBL from preset ('sunset' | 'warehouse' | 'city' | ...) or custom HDRStage — one-component scene staging: lighting, camera fit, shadowsContactShadows — fake soft shadow on a plane; cheaper than shadow mapsFloat — floating/bobbing idle animation for hero objectsShapes / Content
Text — SDF 3D text with font loading, line wrapping, outlinesHtml — embed DOM content in 3D; supports occlude and transformLoaders
useGLTF — load and cache GLTF/GLB; auto-configures Draco CDN decoderuseTexture — load and cache textures; object form for PBR mapsPerformance
Instances / Instance — instanced meshes with simple component APIDetailed — LOD: show different meshes by camera distancePerformanceMonitor — FPS callbacks; pair with AdaptiveDprMaterials
MeshTransmissionMaterial — physically-based glass with refraction and chromatic aberrationimport { useGLTF } from '@react-three/drei'
import { Suspense } from 'react'
function Model(props) {
const { nodes, materials } = useGLTF('/model.glb')
return (
<group {...props} dispose={null}>
<mesh geometry={nodes.Body.geometry} material={materials.Metal} castShadow />
</group>
)
}
useGLTF.preload('/model.glb')
// Wrap in Suspense
<Canvas>
<Suspense fallback={null}>
<Model />
</Suspense>
</Canvas>
# Generate TypeScript component + Draco-compress the GLB
npx gltfjsx model.glb --transform --types --shadows
# Outputs: model-transformed.glb (move to /public) + Model.tsx (move to /src/components)
--transform shrinks most models 70–90% via Draco geometry compression, 1024px texture resize, and WebP conversion.
For clone pattern, KTX2 textures, lazy loading, and parallel preloading, read references/r3f-patterns.md.
Draw call budgets:
The 7 anti-patterns — never do these:
setState inside useFrame — mutate refs directlydelta for animation — never fixed incrementssetState in onPointerMove — mutate refs directlyuseFrame — use store.getState() imperative formvisible prop insteadnew THREE.Vector3() inside useFrame — allocate outside, reuse with .set()useMemo or InstancesDisposal: Always call geometry.dispose() and material.dispose() in useEffect cleanup for dynamically created Three.js objects.
Read references/performance.md for all 7 anti-patterns with wrong/correct code pairs, texture optimization, frustum culling, stats tooling, and mobile rules.
For these topics, read references/extras.md:
useFrame correctness)For the full Rapier v2 API (all collider types, collision events, sensors, joints, forces, InstancedRigidBodies), read references/physics.md.
references/scene-setup.md — Minimal scene template, Canvas defaults, frameloop, responsive canvas, WebGPU rendererreferences/r3f-patterns.md — Canvas props, useFrame, useThree, event system, scroll-driven scenes, GLTF clone pattern, KTX2, lazy loadingreferences/drei-helpers.md — Full Drei inventory by category: every helper with import, key props, and examplereferences/performance.md — All 7 anti-patterns with wrong/correct code, instancing, LOD, texture compression, disposal checklist, mobile rulesreferences/physics.md — Full Rapier v2: colliders, collision events, sensors, 6 joints, forces/impulses, InstancedRigidBodiesreferences/extras.md — Zustand imperative pattern, Leva debug GUI, Rapier quick start, WebGPU bootstraptools
This skill should be used when a Claude Code session needs to keep working after Anthropic usage runs out, or when the user asks to run the Claude Code harness on GPT-5.6 Sol. Trigger phrases include "my Anthropic usage ran out", "I'm out of Claude usage", "usage limit reached, what now", "keep working on another model", "run Claude Code on GPT-5.6 Sol", "use GPT-5.6 Sol as the model", "set up claudex", "claudex isn't working", "route the harness through CLIProxyAPI", or "bill against my ChatGPT/Codex subscription". It stands up a local proxy so the Claude Code CLI runs on OpenAI's Codex backend as an escape hatch, and diagnoses that setup when it drifts. macOS + Homebrew.
testing
This skill should be used when the user asks to "open Visual Wayfinder", "answer a Wayfinder ticket visually", "turn this decision into a configurator", "show Wayfinder choices as a dashboard", "prototype the Wayfinder questionnaire", or wants interactive choice cards, tradeoff controls, rankings, ranges, toggles, and consequence previews for one active Wayfinder decision. It wraps the Wayfinder skill and JSON Render; it never replaces the tracker or resolves more than the active decision.
development
This skill should be used when the user asks to "make a visual proposal", "write this up so I can share it", "present these options visually", "diagram the trade-offs", "turn this plan into something reviewable", or requests a shareable design pitch, architecture proposal, RFC, options comparison, or visual roadmap for work that has not been built. It produces one self-contained, theme-aware HTML page led by grounded diagrams. Use visual-review instead for completed code changes; do not use this skill for internal task tracking.
tools
This skill should be used when the user asks to "add plugin settings", "make a plugin configurable", "store per-project plugin configuration", "use settings.local.json", "create a plugin state file", "expose skill settings in Agent Master", or "add a skill interface". Distinguishes official Claude Code settings from project-owned configuration and documents bOpen Agent Master skill interface discovery.