react-three-fiber is a React renderer for threejs.
Build your scene declaratively with re-usable, self-contained components that react to state, are readily interactive and can participate in React's ecosystem.
npm install three @types/three @react-three/fiberWarning
Three-fiber is a React renderer, it must pair with a major version of React, just like react-dom, react-native, etc. @react-three/fiber@8 pairs with react@18, @react-three/fiber@9 pairs with react@19.
None. Everything that works in Threejs will work here without exception.
No. There is no overhead. Components render outside of React. It outperforms Threejs in scale due to React's scheduling abilities.
Yes. It merely expresses Threejs in JSX, <mesh /> dynamically turns into new THREE.Mesh(). If a new Threejs version adds, removes or changes features, it will be available to you instantly without depending on updates to this library.
| Let's make a re-usable component that has its own state, reacts to user-input and participates in the render-loop. (live demo). |
|
import { createRoot } from 'react-dom/client'
import React, { useRef, useState } from 'react'
import { Canvas, useFrame } from '@react-three/fiber'
function Box(props) {
// This reference gives us direct access to the THREE.Mesh object
const ref = useRef()
// Hold state for hovered and clicked events
const [hovered, hover] = useState(false)
const [clicked, click] = useState(false)
// Subscribe this component to the render-loop, rotate the mesh every frame
useFrame((state, delta) => (ref.current.rotation.x += delta))
// Return the view, these are regular Threejs elements expressed in JSX
return (
<mesh
{...props}
ref={ref}
scale={clicked ? 1.5 : 1}
onClick={(event) => click(!clicked)}
onPointerOver={(event) => hover(true)}
onPointerOut={(event) => hover(false)}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
</mesh>
)
}
createRoot(document.getElementById('root')).render(
<Canvas>
<ambientLight intensity={Math.PI / 2} />
<spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
<pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>,
)Show TypeScript example
npm install @types/threeimport * as THREE from 'three'
import { createRoot } from 'react-dom/client'
import React, { useRef, useState } from 'react'
import { Canvas, useFrame, ThreeElements } from '@react-three/fiber'
function Box(props: ThreeElements['mesh']) {
const ref = useRef<THREE.Mesh>(null!)
const [hovered, hover] = useState(false)
const [clicked, click] = useState(false)
useFrame((state, delta) => (ref.current.rotation.x += delta))
return (
<mesh
{...props}
ref={ref}
scale={clicked ? 1.5 : 1}
onClick={(event) => click(!clicked)}
onPointerOver={(event) => hover(true)}
onPointerOut={(event) => hover(false)}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
</mesh>
)
}
createRoot(document.getElementById('root') as HTMLElement).render(
<Canvas>
<ambientLight intensity={Math.PI / 2} />
<spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
<pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>,
)Live demo: https://codesandbox.io/s/icy-tree-brnsm?file=/src/App.tsx
Show React Native example
This example relies on react 18 and uses expo-cli, but you can create a bare project with their template or with the react-native CLI.
# Install expo-cli, this will create our app
npm install expo-cli -g
# Create app and cd into it
expo init my-app
cd my-app
# Install dependencies
npm install three @react-three/fiber@beta react@rc
# Start
expo startSome configuration may be required to tell the Metro bundler about your assets if you use useLoader or Drei abstractions like useGLTF and useTexture:
// metro.config.js
module.exports = {
resolver: {
sourceExts: ['js', 'jsx', 'json', 'ts', 'tsx', 'cjs'],
assetExts: ['glb', 'png', 'jpg'],
},
}import React, { useRef, useState } from 'react'
import { Canvas, useFrame } from '@react-three/fiber/native'
function Box(props) {
const mesh = useRef(null)
const [hovered, setHover] = useState(false)
const [active, setActive] = useState(false)
useFrame((state, delta) => (mesh.current.rotation.x += delta))
return (
<mesh
{...props}
ref={mesh}
scale={active ? 1.5 : 1}
onClick={(event) => setActive(!active)}
onPointerOver={(event) => setHover(true)}
onPointerOut={(event) => setHover(false)}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
</mesh>
)
}
export default function App() {
return (
<Canvas>
<ambientLight intensity={Math.PI / 2} />
<spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
<pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>
)
}Visit docs.pmnd.rs
You need to be versed in both React and Threejs before rushing into this. If you are unsure about React consult the official React docs, especially the section about hooks. As for Threejs, make sure you at least glance over the following links:
- Make sure you have a basic grasp of Threejs. Keep that site open.
- When you know what a scene is, a camera, mesh, geometry, material, fork the demo above.
- Look up the JSX elements that you see (mesh, ambientLight, etc), all threejs exports are native to three-fiber.
- Try changing some values, scroll through our API to see what the various settings and hooks do.
Some helpful material:
- Threejs-docs and examples
- Discover Threejs, especially the Tips and Tricks chapter for best practices
- Bruno Simons Threejs Journey, arguably the best learning resource, now includes a full R3F chapter
There is a vibrant and extensive eco system around three-fiber, full of libraries, helpers and abstractions.
@react-three/dreiβ useful helpers, this is an eco system in itself@react-three/gltfjsxβ turns GLTFs into JSX components@react-three/postprocessingβ post-processing effects@react-three/uikitβ WebGL rendered UI components for three-fiber@react-three/test-rendererβ for unit tests in node@react-three/offscreenβ offscreen/worker canvas for react-three-fiber@react-three/flexβ flexbox for react-three-fiber@react-three/xrβ VR/AR controllers and events@react-three/csgβ constructive solid geometry@react-three/rapierβ 3D physics using Rapier@react-three/cannonβ 3D physics using Cannon@react-three/p2β 2D physics using P2@react-three/a11yβ real a11y for your scene@react-three/gpu-pathtracerβ realistic path tracingcreate-r3f-app nextβ nextjs starterlaminaβ layer based shader materialszustandβ flux based state managementjotaiβ atoms based state managementvaltioβ proxy based state managementreact-springβ a spring-physics-based animation libraryframer-motion-3dβ framer motion, a popular animation libraryuse-gestureβ mouse/touch gestureslevaβ create GUI controls in secondsmaathβ a kitchen sink for math helpersminiplexβ ECS (entity management system)composer-suiteβ composing shaders, particles, effects and game mechanicstriplexβ visual editor for react-three-fiberkoestlichβ UI component library for react-three-fiber
Usage Trend of the @react-three Family
A small selection of companies and projects relying on three-fiber.
vercel(design agency)basement(design agency)studio freight(design agency)14 islands(design agency)ueno(design agency) β videoflux.ai(PCB builder)colorful.app(modeller)bezi(modeller)readyplayer.me(avatar configurator)zillow(real estate)lumalabs.ai/genie(AI models)skybox.blockadelabs(AI envmaps)3dconfig(floor planer)buerli.io(CAD)getencube(CAD)glowbuzzer(CAD) β videotriplex(editor) β videotheatrejs(editor) β video
If you like this project, please consider helping out. All contributions are welcome as well as donations to Opencollective, or in crypto BTC: 36fuguTPxGCNnYZSRdgdh6Ea94brCAjMbH, ETH: 0x6E3f79Ea1d0dcedeb33D3fC6c34d2B1f156F2682.
Thank you to all our backers! π
This project exists thanks to all the people who contribute.

