# react-three-fiber
> React Three Fiber and Drei patterns for 3D web applications. Use when implementing 3D viewers, loading GLB/GLTF models, configuring orbit controls, handling WebGL, or optimizing 3D performance. Triggers on R3F, Three.js, Canvas, useFrame, useLoader, OrbitControls, GLTFLoader.
- Author: Fernando Velasco
- Repository: fervelgo/laaa-ram
- Version: 20260209000005
- Stars: 0
- Forks: 0
- Last Updated: 2026-02-09
- Source: https://github.com/fervelgo/laaa-ram
- Web: https://mule.run/skillshub/@@fervelgo/laaa-ram~react-three-fiber:20260209000005
---
---
name: react-three-fiber
description: React Three Fiber and Drei patterns for 3D web applications. Use when implementing 3D viewers, loading GLB/GLTF models, configuring orbit controls, handling WebGL, or optimizing 3D performance. Triggers on R3F, Three.js, Canvas, useFrame, useLoader, OrbitControls, GLTFLoader.
allowed-tools: Read, Grep, Glob, Edit, Write
---
# React Three Fiber Development
## Core Patterns
### Basic Canvas Setup
```tsx
'use client'
import { Canvas } from '@react-three/fiber'
import { OrbitControls, Environment, useProgress, Html } from '@react-three/drei'
import { Suspense } from 'react'
function Loader() {
const { progress } = useProgress()
return {progress.toFixed(0)}% loaded
}
export function ObjectViewer({ modelUrl }: { modelUrl: string }) {
return (
)
}
```
### Loading GLB Models
```tsx
import { useGLTF } from '@react-three/drei'
function Model({ url }: { url: string }) {
const { scene } = useGLTF(url)
return
}
// Preload for faster loading
useGLTF.preload('/models/preview/object.glb')
```
### Progressive Loading (Preview -> Full)
```tsx
import { useState, useEffect } from 'react'
import { useGLTF } from '@react-three/drei'
function ProgressiveModel({ previewUrl, fullUrl }: Props) {
const [useFullModel, setUseFullModel] = useState(false)
const preview = useGLTF(previewUrl)
useEffect(() => {
// Preload full model in background
useGLTF.preload(fullUrl)
const timer = setTimeout(() => setUseFullModel(true), 100)
return () => clearTimeout(timer)
}, [fullUrl])
const full = useGLTF(fullUrl, true) // true = don't block
return
}
```
### Mobile Touch Controls
```tsx
```
### Auto-Rotate Toggle
```tsx
function Controls({ autoRotate }: { autoRotate: boolean }) {
const controlsRef = useRef(null)
return (
)
}
```
### Reset Camera Position
```tsx
import { useThree } from '@react-three/fiber'
function ResetButton() {
const { camera } = useThree()
const defaultPosition = new Vector3(0, 0, 5)
const reset = () => {
camera.position.copy(defaultPosition)
camera.lookAt(0, 0, 0)
}
return
}
```
## Performance Optimization
### Frame Rate Management
```tsx
import { useFrame } from '@react-three/fiber'
function Model() {
const ref = useRef(null)
// Only update when needed
useFrame((state, delta) => {
if (ref.current && autoRotate) {
ref.current.rotation.y += delta * 0.5
}
})
return ...
}
```
### Dispose Resources
```tsx
useEffect(() => {
return () => {
// Clean up on unmount
scene.traverse((child) => {
if (child instanceof THREE.Mesh) {
child.geometry.dispose()
if (child.material instanceof THREE.Material) {
child.material.dispose()
}
}
})
}
}, [scene])
```
### WebGL Fallback
```tsx
function Viewer({ modelUrl, fallbackImage }: Props) {
const [webglSupported, setWebglSupported] = useState(true)
useEffect(() => {
try {
const canvas = document.createElement('canvas')
const gl = canvas.getContext('webgl') || canvas.getContext('webgl2')
setWebglSupported(!!gl)
} catch {
setWebglSupported(false)
}
}, [])
if (!webglSupported) {
return (
WebGL is not supported in your browser
)
}
return
}
```
## Common Issues
| Issue | Solution |
|-------|----------|
| Model too dark | Add `` |
| Controls not working | Ensure Canvas has size (height/width) |
| Model not centered | Use `
` from Drei |
| Poor mobile performance | Reduce `dpr`, use simpler models |
| Memory leaks | Dispose geometries and materials on unmount |