
R3f Loaders
Load GLTF/GLB models, textures, and HDR environments in React Three Fiber without breaking Suspense or duplicate fetch storms.
Overview
r3f-loaders is an agent skill for the Build phase that teaches React Three Fiber patterns for loading 3D models and textures with useGLTF, useLoader, Suspense, and preloading.
Install
npx skills add https://github.com/enzed/r3f-skills --skill r3f-loadersWhat is this skill?
- Documents useGLTF with scene, nodes, materials, and animations extraction
- Covers useLoader, Suspense boundaries, and preloading patterns for R3F
- Shows OrbitControls and primitive object mounting for imported GLB scenes
- Quick-start Canvas setup for solo builders prototyping 3D in React
Adoption & trust: 609 installs on skills.sh; 89 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You have a React Three Fiber scene but models stall the frame, error outside Suspense, or reload on every route change.
Who is it for?
Solo builders adding a GLB product viewer, lightweight WebGL demo, or R3F prototype who need copy-paste loader patterns.
Skip if: Teams building native mobile 3D, pure Three.js without React, or pipelines that only need Blender export settings with no R3F code.
When should I use this skill?
Loading 3D models, textures, HDR environments, or managing loading states in React Three Fiber.
What do I get? / Deliverables
After running the skill, your agent implements Drei-backed loaders, Suspense boundaries, and preload calls so GLB assets mount predictably in the Canvas.
- R3F components using useGLTF or useLoader
- Suspense-wrapped Canvas trees with preload configuration
Recommended Skills
Journey fit
3D asset loading is implemented when the product UI or immersive scene is being built, before ship-time performance tuning. Canonical shelf is frontend because the skill centers on Canvas, Drei hooks, and React Suspense—not backend APIs or ops.
How it compares
Use instead of guessing Drei hook signatures from scattered Stack Overflow snippets when you want one R3F-focused loader playbook.
Common Questions / FAQ
Who is r3f-loaders for?
Indie front-end developers and solo founders using React Three Fiber who need reliable GLTF loading and Suspense wiring in agent-assisted coding sessions.
When should I use r3f-loaders?
During Build (frontend) when integrating 3D assets; also when debugging blank canvases or flicker right before Ship (perf) tuning on WebGL routes.
Is r3f-loaders safe to install?
Review the Security Audits panel on this Prism page and inspect the skill source in your repo before granting filesystem or network access to your agent.
SKILL.md
READMESKILL.md - R3f Loaders
# React Three Fiber Loaders ## Quick Start ```tsx import { Canvas } from '@react-three/fiber' import { useGLTF, OrbitControls } from '@react-three/drei' import { Suspense } from 'react' function Model() { const { scene } = useGLTF('/models/robot.glb') return <primitive object={scene} /> } export default function App() { return ( <Canvas> <ambientLight /> <Suspense fallback={null}> <Model /> </Suspense> <OrbitControls /> </Canvas> ) } ``` ## useGLTF (Drei) The recommended way to load GLTF/GLB models. ### Basic Usage ```tsx import { useGLTF } from '@react-three/drei' function Model() { const gltf = useGLTF('/models/robot.glb') // gltf contains: // - scene: THREE.Group (the main scene) // - nodes: Object of named meshes // - materials: Object of named materials // - animations: Array of AnimationClip return <primitive object={gltf.scene} /> } ``` ### Using Nodes and Materials ```tsx function Model() { const { nodes, materials } = useGLTF('/models/robot.glb') return ( <group> {/* Use specific meshes */} <mesh geometry={nodes.Body.geometry} material={materials.Metal} position={[0, 0, 0]} /> <mesh geometry={nodes.Head.geometry} material={materials.Plastic} position={[0, 1, 0]} /> </group> ) } ``` ### With TypeScript (gltfjsx) Generate typed components using gltfjsx: ```bash npx gltfjsx model.glb --types ``` ```tsx // Generated component import { useGLTF } from '@react-three/drei' import { GLTF } from 'three-stdlib' type GLTFResult = GLTF & { nodes: { Body: THREE.Mesh Head: THREE.Mesh } materials: { Metal: THREE.MeshStandardMaterial Plastic: THREE.MeshStandardMaterial } } export function Model(props: JSX.IntrinsicElements['group']) { const { nodes, materials } = useGLTF('/model.glb') as GLTFResult return ( <group {...props} dispose={null}> <mesh geometry={nodes.Body.geometry} material={materials.Metal} /> <mesh geometry={nodes.Head.geometry} material={materials.Plastic} /> </group> ) } useGLTF.preload('/model.glb') ``` ### Draco Compression ```tsx import { useGLTF } from '@react-three/drei' function Model() { // Drei automatically handles Draco if the file is Draco-compressed const { scene } = useGLTF('/models/compressed.glb') return <primitive object={scene} /> } // Or specify Draco decoder path useGLTF.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.5.6/') ``` ### Preloading ```tsx import { useGLTF } from '@react-three/drei' // Preload at module level useGLTF.preload('/models/robot.glb') useGLTF.preload(['/model1.glb', '/model2.glb']) function Model() { // Will be instant if preloaded const { scene } = useGLTF('/models/robot.glb') return <primitive object={scene} /> } ``` ### Processing Loaded Model ```tsx function Model() { const { scene } = useGLTF('/models/robot.glb') useEffect(() => { // Enable shadows on all meshes scene.traverse((child) => { if (child.isMesh) { child.castShadow = true child.receiveShadow = true } }) }, [scene]) return <primitive object={scene} /> } ``` ## useLoader (Core R3F) For loading any Three.js asset. ### Basic Texture Loading ```tsx import { useLoader } from '@react-three/fiber' import { TextureLoader } from 'three' function TexturedMesh() { const texture = useLoader(TextureLoader, '/textures/color.jpg') return ( <mesh> <boxGeometry /> <meshStandardMaterial map={texture} /> </mesh> ) } ``` ### Multiple Assets ```tsx function MultiTexture() { const [colorMap, normalMap, roughnessMap] = useLoader(TextureLoader, [ '/textures/color.jpg', '/texture