react-three-fiber is a React renderer for Three.js. Instead of writing imperative Three.js code, you describe scenes as JSX: <mesh /> becomes new THREE.Mesh() under the hood. It's built for React developers who want to bring 3D graphics into their component tree, and for Three.js developers who want state management, hooks, and reusable components without giving up direct access to the underlying objects.
Components render outside of React's normal reconciliation for the 3D scene graph, so there's no performance penalty compared to plain Three.js. Because every Three.js class is exposed as a JSX tag automatically, new Three.js features and updates are available immediately, without waiting on the library to catch up.
onClick, onPointerOver, and similar events work directly on 3D objects like they do on DOM elements./native entry point renders 3D scenes in Expo or bare React Native apps.ThreeElements, with @types/three for the underlying library.Use react-three-fiber when you're already building in React and need interactive 3D: product configurators, data visualizations, portfolio sites, game-like interfaces, or WebGL-based UI elements that need to react to component state or user input. It fits well when a scene needs to be composed from reusable, self-contained components, each managing its own hover/click/animation state, similar to how you'd structure any React UI.
It's also a good fit for teams that want to combine 3D rendering with the rest of the React ecosystem (state managers like zustand or jotai, gesture libraries, animation libraries) rather than hand-rolling that integration on top of vanilla Three.js.
It's not the right choice if you don't know React or Three.js fundamentals; the README is explicit that you need a working grasp of both before starting. If your project is a one-off static 3D render with no interactivity or component reuse, plain Three.js without a framework may be simpler. Teams building React Native apps should note some extra Metro bundler configuration is needed for asset loading (GLTF, textures).
Install Three.js, its type definitions, and the renderer:
npm install three @types/three @react-three/fiber
react-three-fiber is a React renderer, so it must be paired with a matching React major version, similar to react-dom or react-native. Version 8 of the library pairs with React 18; version 9 pairs with React 19.
Basic usage in a web app:
import { createRoot } from 'react-dom/client'
import { Canvas, useFrame } from '@react-three/fiber'
createRoot(document.getElementById('root')).render(
<Canvas>
<ambientLight intensity={Math.PI / 2} />
<mesh>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="orange" />
</mesh>
</Canvas>,
)
For React Native (via Expo):
npm install expo-cli -g
expo init my-app
cd my-app
npm install three @react-three/fiber@beta react@rc
expo start
React Native projects using useLoader or drei helpers like useGLTF need Metro configured to recognize 3D asset extensions:
// metro.config.js
module.exports = {
resolver: {
sourceExts: ['js', 'jsx', 'json', 'ts', 'tsx', 'cjs'],
assetExts: ['glb', 'png', 'jpg'],
},
}
Import from @react-three/fiber/native instead of the default entry point when targeting React Native.