This skill should be used when building Three.js or React Three Fiber (R3F) projects, creating 3D scenes, animating meshes with useFrame, loading GLTF/GLB models, setting up physics with @react-three/rapier, using WebGPU with R3F, optimizing 3D performance, scaffolding Vite+R3F projects, or exporting R3F components. Covers scene setup, Drei helpers, asset pipeline, responsive canvas, and performance budgets.
From bopen-toolsnpx claudepluginhub b-open-io/claude-plugins --plugin bopen-toolsThis skill uses the workspace's default tool permissions.
README.mdreferences/drei-helpers.mdreferences/extras.mdreferences/performance.mdreferences/physics.mdreferences/r3f-patterns.mdreferences/scene-setup.mdSearches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
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