React Three Fiber
Full documentation content.
---
Introduction
URL: https://r3f.docs.pmnd.rs/getting-started/introduction
Description: React-three-fiber is a React renderer for three.js.
Build your scene declaratively with re-usable, self-contained components that react to state, are readily interactive and can participate in [React](https://react.dev)'s ecosystem.
[](/getting-started/examples)
```bash
npm install three @types/three @react-three/fiber
```
> [!WARNING]
> 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.
## Does it have limitations?
None. Everything that works in Threejs will work here without exception.
## Is it slower than plain Threejs?
No. There is no overhead. Components render outside of React. It outperforms Threejs in scale due to React's scheduling abilities.
## Can it keep up with frequent feature updates to Threejs?
Yes. It merely expresses Threejs in JSX, `` 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.
## What does it look like?
Let's make a re-usable component that has its own state, reacts to user-input and participates in the render-loop:
Show TypeScript example
```bash
npm install @types/three
```
(null!)
const [hovered, setHover] = useState(false)
const [active, setActive] = useState(false)
useFrame((state, delta) => (meshRef.current.rotation.x += delta))
return (
setActive(!active)}
onPointerOver={(event) => setHover(true)}
onPointerOut={(event) => setHover(false)}>
)
}
createRoot(document.getElementById('root')).render(
,
)`,
}}
/>
Show React Native example
For installation instructions see [react native installation instructions](/getting-started/installation#react-native).
```jsx
import React, { useRef, useState } from 'react'
import { Canvas, useFrame } from '@react-three/fiber/native'
function Box(props) {
const meshRef = useRef(null)
const [hovered, setHover] = useState(false)
const [active, setActive] = useState(false)
useFrame((state, delta) => (meshRef.current.rotation.x += delta))
return (
setActive(!active)}
onPointerOver={(event) => setHover(true)}
onPointerOut={(event) => setHover(false)}>
)
}
export default function App() {
return (
)
}
```
## First steps
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](https://react.dev/learn), especially [the section about hooks](https://react.dev/reference/react). As for Threejs, make sure you at least glance over the following links:
1. Make sure you have a [basic grasp of Threejs](https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene). Keep that site open.
2. When you know what a scene is, a camera, mesh, geometry, material, fork the [demo above](https://github.com/pmndrs/react-three-fiber#what-does-it-look-like).
3. [Look up](https://threejs.org/docs/index.html#api/en/objects/Mesh) the JSX elements that you see (mesh, ambientLight, etc), _all_ threejs exports are native to three-fiber.
4. Try changing some values, scroll through our [API](/api/canvas) to see what the various settings and hooks do.
Some helpful material:
- [Threejs-docs](https://threejs.org/docs) and [examples](https://threejs.org/examples)
- [Discover Threejs](https://discoverthreejs.com), especially the [Tips and Tricks](https://discoverthreejs.com/tips-and-tricks) chapter for best practices
- [Bruno Simons Threejs Journey](https://threejs-journey.com), arguably the best learning resource, now includes a full [R3F chapter](https://threejs-journey.com/lessons/what-are-react-and-react-three-fiber)
## Eco system
There is a vibrant and extensive eco system around three-fiber, full of libraries, helpers and abstractions.
- [`@react-three/drei`](https://github.com/pmndrs/drei) – useful helpers, this is an eco system in itself
- [`@react-three/gltfjsx`](https://github.com/pmndrs/gltfjsx) – turns GLTFs into JSX components
- [`@react-three/postprocessing`](https://github.com/pmndrs/react-postprocessing) – post-processing effects
- [`@react-three/test-renderer`](https://github.com/pmndrs/react-three-fiber/tree/master/packages/test-renderer) – for unit tests in node
- [`@react-three/flex`](https://github.com/pmndrs/react-three-flex) – flexbox for react-three-fiber
- [`@react-three/xr`](https://github.com/pmndrs/react-xr) – VR/AR controllers and events
- [`@react-three/csg`](https://github.com/pmndrs/react-three-csg) – constructive solid geometry
- [`@react-three/rapier`](https://github.com/pmndrs/react-three-rapier) – 3D physics using Rapier
- [`@react-three/cannon`](https://github.com/pmndrs/use-cannon) – 3D physics using Cannon
- [`@react-three/p2`](https://github.com/pmndrs/use-p2) – 2D physics using P2
- [`@react-three/a11y`](https://github.com/pmndrs/react-three-a11y) – real a11y for your scene
- [`@react-three/gpu-pathtracer`](https://github.com/pmndrs/react-three-gpu-pathtracer) – realistic path tracing
- [`create-r3f-app next`](https://github.com/pmndrs/react-three-next) – nextjs starter
- [`lamina`](https://github.com/pmndrs/lamina) – layer based shader materials
- [`zustand`](https://github.com/pmndrs/zustand) – flux based state management
- [`jotai`](https://github.com/pmndrs/jotai) – atoms based state management
- [`valtio`](https://github.com/pmndrs/valtio) – proxy based state management
- [`react-spring`](https://github.com/pmndrs/react-spring) – a spring-physics-based animation library
- [`framer-motion-3d`](https://www.framer.com/docs/three-introduction/) – framer motion, a popular animation library
- [`use-gesture`](https://github.com/pmndrs/react-use-gesture) – mouse/touch gestures
- [`leva`](https://github.com/pmndrs/leva) – create GUI controls in seconds
- [`maath`](https://github.com/pmndrs/maath) – a kitchen sink for math helpers
- [`miniplex`](https://github.com/hmans/miniplex) – ECS (entity management system)
- [`composer-suite`](https://github.com/hmans/composer-suite) – composing shaders, particles, effects and game mechanics
## How to contribute
If you like this project, please consider helping out. All contributions are welcome as well as donations to [Opencollective](https://opencollective.com/react-three-fiber), or in crypto `BTC: 36fuguTPxGCNnYZSRdgdh6Ea94brCAjMbH`, `ETH: 0x6E3f79Ea1d0dcedeb33D3fC6c34d2B1f156F2682`.
## Backers
Thank you to all our backers! 🙏
## Contributors
This project exists thanks to all the people who contribute.
---
Installation
URL: https://r3f.docs.pmnd.rs/getting-started/installation
Description: Learn how to install react-three-fiber
```bash
npm install three @react-three/fiber
```
> [!WARNING]
> Fiber is compatible with React v18 and v19 and works with ReactDOM and React Native. 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.
Getting started with React Three Fiber is not nearly as hard as you might have thought, but various frameworks may require particular attention.
We've put together guides for getting started with each popular framework:
- Vite.js
- Next.js
- CDN w/o build tools
- React Native
If you just want to give it a try, fork this [example on codesandbox](https://codesandbox.io/s/rrppl0y8l4?file=/src/App.js)!
## Vite.js
`vite` will also work out of the box.
```bash
# Create app
npm create vite my-app
# Select react as framework
# Install dependencies
cd my-app
npm install three @react-three/fiber
# Start development server
npm run dev
```
## Next.js
It should work out of the box but you will encounter untranspiled add-ons in the three.js ecosystem, in that case,
### Next.js 13.1 or latest version
You need to add three to `transpilePackages` property in `next.config.js`:
```js
transpilePackages: ['three'],
```
### Next.js 13.0 or oldest version
You can install the `next-transpile-modules` module:
```bash
npm install next-transpile-modules --save-dev
```
then, add this to your `next.config.js`
```js
const withTM = require('next-transpile-modules')(['three'])
module.exports = withTM()
```
Make sure to check out our [official next.js starter](https://github.com/pmndrs/react-three-next), too!
## Without build tools
You can use React Three Fiber with browser-ready ES Modules from [esm.sh](https://esm.sh) and a JSX-like syntax powered by [htm](https://github.com/developit/htm).
```jsx
import ReactDOM from 'https://esm.sh/react-dom'
import React, { useRef, useState } from 'https://esm.sh/react'
import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber'
import htm from 'https://esm.sh/htm'
const html = htm.bind(React.createElement)
ReactDOM.render(html`<${Canvas}>.../>`, document.getElementById('root'))
```
Full example
```jsx
import ReactDOM from 'https://esm.sh/react-dom'
import React, { useRef, useState } from 'https://esm.sh/react'
import { Canvas, useFrame } from 'https://esm.sh/@react-three/fiber'
import htm from 'https://esm.sh/htm'
const html = htm.bind(React.createElement)
function Box(props) {
const meshRef = useRef()
const [hovered, setHover] = useState(false)
const [active, setActive] = useState(false)
useFrame(() => (meshRef.current.rotation.x = meshRef.current.rotation.y += 0.01))
return html` setActive(!active)}
onPointerOver=${() => setHover(true)}
onPointerOut=${() => setHover(false)}
>
`
}
ReactDOM.render(
html` <${Canvas}>
<${Box} position=${[-1.2, 0, 0]} />
<${Box} position=${[1.2, 0, 0]} />
/>`,
document.getElementById('root'),
)
```
## React Native
R3F v8 adds support for react-native and can be imported from `@react-three/fiber/native`. We use `expo-gl` and `expo-asset` under the hood for WebGL2 bindings and ensuring interplay between Metro and three.js loaders.
To get started, create an app via `expo` or `react-native`:
```bash
# Create a managed/bare app
npx create-expo-app
cd my-app
# or
# Create and link bare app
npx react-native init my-app
npx install-expo-modules@latest
cd my-app
```
Then install dependencies (for manual installation or migration, see [expo modules installation](https://docs.expo.dev/bare/installing-expo-modules)):
```bash
# Automatically install
expo install expo-gl
# Install NPM dependencies
npm install three @react-three/fiber
```
Some configuration may be required to tell the Metro bundler about your assets if you use `useLoader` or Drei abstractions like `useGLTF` and `useTexture`:
```js
// metro.config.js
module.exports = {
resolver: {
sourceExts: ['js', 'jsx', 'json', 'ts', 'tsx', 'cjs', 'mjs'],
assetExts: ['glb', 'gltf', 'png', 'jpg'],
},
}
```
R3F's API is completely x-platform, so you can use [events](/api/events) and [hooks](/api/hooks) just as you would on the web.
> [!NOTE]
> Make sure to import from `@react-three/fiber/native` or `@react-three/drei/native` for correct IntelliSense and platform-specific abstractions.
> [!NOTE]
> iOS simulators often have incomplete or unreliable OpenGL ES support, which can cause EXC_BAD_ACCESS crashes when rendering 3D content. Always test on a physical iOS device (iPhone/iPad running iOS 16 or later) to ensure stable WebGL rendering.
```jsx
import { Suspense } from 'react'
import { Canvas } from '@react-three/fiber/native'
import { useGLTF } from '@react-three/drei/native'
import modelPath from './path/to/model.glb'
function Model(props) {
const gltf = useGLTF(modelPath)
return
}
export default function App() {
return (
)
}
```
---
Your first scene
URL: https://r3f.docs.pmnd.rs/getting-started/your-first-scene
Description: This guide will help you setup your first React Three Fiber scene and introduce you to its core concepts.
This tutorial will assume some React knowledge.
## Setting up the Canvas
We'll start by importing the `` component from `@react-three/fiber` and putting it in our React tree.
```jsx
import { createRoot } from 'react-dom/client'
import { Canvas } from '@react-three/fiber'
function App() {
return (
)
}
createRoot(document.getElementById('root')).render()
```
The Canvas component does some important setup work behind the scenes:
- It sets up a **Scene** and a **Camera**, the basic building blocks necessary for rendering
- It renders our scene every frame, you do not need a traditional render-loop
> [!NOTE]
> Canvas is responsive to fit the parent node, so you can control how big it is by changing the parents width and height, in this case #canvas-container.
## Adding a Mesh Component
To actually see something in our scene, we'll add a lowercase `` native element, which is the direct equivalent to new THREE.Mesh().
```js