# React Three Fiber (R3F) Documentation
# Source: https://raw.githubusercontent.com/pmndrs/react-three-fiber/master/docs/getting-started/installation.mdx
# Path: docs/getting-started/installation.mdx

---
title: Installation
description: Learn how to install react-three-fiber
nav: 1
---

```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'))
```

<details>
<summary>Full example</summary>

```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` <mesh
    ...${props}
    ref=${meshRef}
    scale=${active ? 1.5 : 1}
    onClick=${() => setActive(!active)}
    onPointerOver=${() => setHover(true)}
    onPointerOut=${() => setHover(false)}
  >
    <boxGeometry args=${[1, 1, 1]} />
    <meshStandardMaterial color=${hovered ? 'hotpink' : 'orange'} />
  </mesh>`
}

ReactDOM.render(
  html` <${Canvas}>
    <ambientLight />
    <pointLight position=${[10, 10, 10]} />
    <${Box} position=${[-1.2, 0, 0]} />
    <${Box} position=${[1.2, 0, 0]} />
  <//>`,
  document.getElementById('root'),
)
```

</details>

## 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 <primitive {...props} object={gltf.scene} />
}

export default function App() {
  return (
    <Canvas>
      <ambientLight />
      <Suspense>
        <Model />
      </Suspense>
    </Canvas>
  )
}
```