react-three-fiber README

The project's README from github.com/pmndrs/react-three-fiber. As one markdown file: README.md.

@react-three/fiber

Version Downloads Twitter Discord Open Collective ETH BTC

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/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, <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.

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. (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/three
import * 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 start

Some 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>
  )
}

Documentation, tutorials, examples

Visit docs.pmnd.rs

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, especially the section about hooks. As for Threejs, make sure you at least glance over the following links:

  1. Make sure you have a basic grasp of Threejs. Keep that site open.
  2. When you know what a scene is, a camera, mesh, geometry, material, fork the demo above.
  3. Look up 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 to see what the various settings and hooks do.

Some helpful material:

Ecosystem

There is a vibrant and extensive ecosystem around three-fiber, full of libraries, helpers and abstractions.

Usage Trend of the @react-three Family

Who is using Three-fiber

A small selection of companies and projects relying on three-fiber.

How to contribute

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.

Backers

Thank you to all our backers! 🙏

Contributors

This project exists thanks to all the people who contribute.

react-three-fiber (pmndrs/react-three-fiber)

webgl
Searching Database…

What is this?react-three-fiber is a React renderer for Three.js: you build 3D scenes declaratively with reusable, self-contained components that react to state, are readily interactive and plug into the whole React ecosystem.
So is it a replacement for Three.js, or a layer on top of it?A thin layer: it is a React renderer, just like react-dom or react-native. It expresses Three.js in JSX — a mesh element in your markup dynamically becomes a new THREE.Mesh().
How do I add it to a project?Install the @react-three/fiber npm package alongside three: version 8 pairs with React 18, version 9 with React 19. There is also a create-r3f-app Next.js starter.
Do I need to know React and Three.js before using it?Yes — the README is explicit that you should be versed in both. That means React, especially hooks, and the Three.js basics: scenes, cameras, meshes, geometry and materials.
Are there any limitations compared to raw Three.js?None — everything that works in Three.js works here without exception. New Three.js features become available instantly too, without waiting for updates to this library.
Who is using it in production?Design agencies (Vercel, basement, studio freight, 14 islands, ueno), plus flux.ai (PCB builder), readyplayer.me (avatar configurator), Zillow, Lumalabs' Genie and several CAD tools and 3D editors.
Does it work outside the browser, like in React Native?Yes, there is a React Native example built on React 18, using expo-cli or a bare react-native CLI project. Using useLoader or Drei helpers like useGLTF may require Metro bundler configuration for your assets.
What is Drei?@react-three/drei is the flagship helper package of the ecosystem — the README calls it an ecosystem in itself. It provides ready-made abstractions like useGLTF and useTexture for loading assets.
Where are the docs, and what is the best way to learn it?Official docs live at docs.pmnd.rs. The README advises starting from the official React docs (especially hooks) and the Three.js docs, and singles out Bruno Simon's Three.js Journey course, which includes a full react-three-fiber chapter.
Can I edit scenes visually instead of writing JSX?Yes — triplex is a visual editor for react-three-fiber, and theatrejs is also listed as an editor in the ecosystem section.
Creator
pmndrs
Size
30.8 MB
Stars
33K
Age
7y
Commits · 90 Days