> react-three-fiber
You are an expert in React Three Fiber (R3F), the React renderer for Three.js that lets developers build 3D scenes using JSX components. You help teams create interactive 3D websites, product configurators, data visualizations, games, and immersive experiences — using React patterns (hooks, state, props, suspense) instead of imperative Three.js code, with full access to the Three.js ecosystem.
curl "https://skillshub.wtf/TerminalSkills/skills/react-three-fiber?format=md"React Three Fiber — Declarative Three.js for React
You are an expert in React Three Fiber (R3F), the React renderer for Three.js that lets developers build 3D scenes using JSX components. You help teams create interactive 3D websites, product configurators, data visualizations, games, and immersive experiences — using React patterns (hooks, state, props, suspense) instead of imperative Three.js code, with full access to the Three.js ecosystem.
Core Capabilities
Canvas and Scene Setup
import { Canvas } from "@react-three/fiber";
function App() {
return (
<Canvas
camera={{ position: [0, 2, 5], fov: 50 }}
dpr={[1, 2]} // Adaptive pixel ratio
gl={{ antialias: true, alpha: true }}
shadows // Enable shadow maps
>
<ambientLight intensity={0.4} />
<directionalLight position={[5, 5, 5]} castShadow />
<mesh position={[0, 1, 0]} castShadow>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="orange" />
</mesh>
<mesh rotation={[-Math.PI / 2, 0, 0]} receiveShadow>
<planeGeometry args={[10, 10]} />
<meshStandardMaterial color="#444" />
</mesh>
</Canvas>
);
}
Hooks
import { useFrame, useThree, useLoader } from "@react-three/fiber";
import { useRef } from "react";
import * as THREE from "three";
function SpinningBox() {
const meshRef = useRef<THREE.Mesh>(null);
const { viewport, camera } = useThree(); // Access Three.js internals
// Runs every frame (60fps game loop)
useFrame((state, delta) => {
if (meshRef.current) {
meshRef.current.rotation.y += delta; // Frame-rate independent
// Hover effect: follow mouse
meshRef.current.position.x = THREE.MathUtils.lerp(
meshRef.current.position.x,
(state.pointer.x * viewport.width) / 2,
0.1,
);
}
});
return (
<mesh ref={meshRef}>
<boxGeometry />
<meshStandardMaterial color="hotpink" />
</mesh>
);
}
Loading 3D Models
import { useGLTF, useAnimations } from "@react-three/drei";
import { useEffect } from "react";
function Character({ animation = "idle" }) {
const { scene, animations } = useGLTF("/models/character.glb");
const { actions } = useAnimations(animations, scene);
useEffect(() => {
actions[animation]?.reset().fadeIn(0.3).play();
return () => { actions[animation]?.fadeOut(0.3); };
}, [animation, actions]);
return <primitive object={scene} scale={1.5} />;
}
useGLTF.preload("/models/character.glb");
Events and Interaction
function InteractiveBox() {
const [hovered, setHovered] = useState(false);
const [clicked, setClicked] = useState(false);
return (
<mesh
scale={clicked ? 1.5 : 1}
onClick={() => setClicked(!clicked)}
onPointerOver={() => setHovered(true)}
onPointerOut={() => setHovered(false)}
>
<boxGeometry />
<meshStandardMaterial color={hovered ? "hotpink" : "orange"} />
</mesh>
);
}
// R3F raycasts pointer events automatically — same API as DOM events
Installation
npm install three @react-three/fiber
npm install @react-three/drei # Essential helpers
npm install @react-three/postprocessing # Visual effects
Best Practices
- Everything is a component — Meshes, lights, cameras, groups are all JSX; compose scenes like React UIs
- useFrame for animation — Never use
requestAnimationFrame;useFrameintegrates with R3F's render loop - Drei for shortcuts — Use
@react-three/dreifor OrbitControls, Environment, Text, Html, loaders; saves weeks of work - Suspense for loading — Wrap
<Canvas>children in<Suspense fallback={...}>for loading states - GLTF for models — Use
.glbformat; compress with Draco (npx gltfjsx model.glb --draco); preload withuseGLTF.preload - Adaptive performance — Use
<AdaptiveDpr>and<PerformanceMonitor>from Drei; degrade quality on slow devices - Pointer events — R3F raycasts automatically;
onClick,onPointerOverwork like DOM events on any mesh - Instances for performance — Use
<Instances>or<InstancedMesh>for 100+ identical objects (trees, particles, stars)
> related_skills --same-repo
> zustand
You are an expert in Zustand, the small, fast, and scalable state management library for React. You help developers manage global state without boilerplate using Zustand's hook-based stores, selectors for performance, middleware (persist, devtools, immer), computed values, and async actions — replacing Redux complexity with a simple, un-opinionated API in under 1KB.
> zoho
Integrate and automate Zoho products. Use when a user asks to work with Zoho CRM, Zoho Books, Zoho Desk, Zoho Projects, Zoho Mail, or Zoho Creator, build custom integrations via Zoho APIs, automate workflows with Deluge scripting, sync data between Zoho apps and external systems, manage leads and deals, automate invoicing, build custom Zoho Creator apps, set up webhooks, or manage Zoho organization settings. Covers Zoho CRM, Books, Desk, Projects, Creator, and cross-product integrations.
> zod
You are an expert in Zod, the TypeScript-first schema declaration and validation library. You help developers define schemas that validate data at runtime AND infer TypeScript types at compile time — eliminating the need to write types and validators separately. Used for API input validation, form validation, environment variables, config files, and any data boundary.
> zipkin
Deploy and configure Zipkin for distributed tracing and request flow visualization. Use when a user needs to set up trace collection, instrument Java/Spring or other services with Zipkin, analyze service dependencies, or configure storage backends for trace data.