skills/threejs-r3f/SKILL.md
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.
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 bootstrapdevelopment
This skill should be used when the user asks to "design a business card", "make a printable PDF", "render HTML to PDF", "generate a postcard", "build print collateral", "set up an HTML print pipeline", or needs help with bleed, safe areas, font embedding, or QR generation for print. Provides a Playwright-based pipeline with multiple bundled templates and theme variants for business cards (minimal, watercolor light, watercolor dark) and instructions for adding new templates.
tools
Get recent tweets from an X/Twitter user. Use when user asks "what has @username posted", "recent tweets from", "user's X posts", "show timeline for", "what is @user saying". Requires X_BEARER_TOKEN.
data-ai
Get X/Twitter user profile by username. Use when user asks "who is @username", "get X profile", "lookup Twitter user", "find X account", "user details", "follower count for". Requires X_BEARER_TOKEN.
data-ai
Search recent X/Twitter posts by query. Returns RAW TWEETS (last 7 days). Use when user asks "search X for", "find tweets about", "what are people saying about", "Twitter search", "raw tweets about". For AI summaries/sentiment, use x-research instead. Requires X_BEARER_TOKEN.