Help us improve
Share bugs, ideas, or general feedback.
From bopen-tools
Builds Three.js and React Three Fiber (R3F) projects: 3D scenes, useFrame animations, GLTF/GLB models, Rapier physics, WebGPU, performance optimization, Vite scaffolding, Drei helpers.
npx claudepluginhub b-open-io/claude-plugins --plugin bopen-toolsHow this skill is triggered — by the user, by Claude, or both
Slash command
/bopen-tools:threejs-r3fThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Guide for building 3D web experiences with R3F v9 (React 19) and the pmndrs ecosystem.
Build declarative 3D scenes with React Three Fiber in React apps using JSX components for Three.js objects. For interactive configurators, games, portfolios, and data viz.
Builds interactive 3D web scenes with Three.js using WebGL/WebGPU. Guides on scenes, cameras, renderers, geometries, materials, meshes, lights, animations, and OrbitControls.
Builds interactive 3D web experiences with Three.js, React Three Fiber, Spline, WebGL, and GLSL shaders for product configurators, 3D portfolios, immersive sites, and performance optimization.
Share bugs, ideas, or general feedback.
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 bootstrap