Top Related Projects
JavaScript 3D Library.
Babylon.js is a powerful, beautiful, simple, and open game and rendering engine packed into a friendly JavaScript framework.
glTF – Runtime 3D Asset Delivery
JavaScript game engine built on WebGL, WebGPU, WebXR and glTF
React component for Spline scenes.
✌️ A spring physics based React animation library
Quick Overview
React Three Fiber is a popular React renderer for Three.js, a powerful 3D graphics library for the web. It allows developers to create and manipulate 3D scenes using React's declarative syntax, making it easier to integrate 3D graphics into React applications.
Pros
- Seamless integration with React ecosystem and components
- Simplified 3D scene creation using declarative syntax
- Automatic performance optimizations and efficient rendering
- Large and active community with extensive documentation and examples
Cons
- Steep learning curve for developers new to 3D graphics
- Performance limitations for complex scenes compared to vanilla Three.js
- Potential compatibility issues with some Three.js plugins and extensions
- Requires understanding of both React and Three.js concepts
Code Examples
- Creating a simple 3D scene with a rotating cube:
import React, { useRef } from 'react'
import { Canvas, useFrame } from '@react-three/fiber'
function RotatingCube() {
const meshRef = useRef()
useFrame(() => (meshRef.current.rotation.x += 0.01))
return (
<mesh ref={meshRef}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="orange" />
</mesh>
)
}
function App() {
return (
<Canvas>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<RotatingCube />
</Canvas>
)
}
- Adding user interaction with mouse events:
import { useThree } from '@react-three/fiber'
function InteractiveSphere() {
const { viewport } = useThree()
return (
<mesh
onClick={(e) => console.log('clicked')}
onPointerOver={(e) => console.log('hovered')}
onPointerOut={(e) => console.log('unhovered')}
>
<sphereGeometry args={[1, 32, 32]} />
<meshStandardMaterial color="royalblue" />
</mesh>
)
}
- Using hooks for animation:
import { useFrame } from '@react-three/fiber'
function AnimatedTorus() {
const meshRef = useRef()
useFrame((state, delta) => {
meshRef.current.rotation.x += delta
meshRef.current.position.y = Math.sin(state.clock.elapsedTime) * 2
})
return (
<mesh ref={meshRef}>
<torusGeometry args={[1, 0.4, 16, 100]} />
<meshNormalMaterial />
</mesh>
)
}
Getting Started
To start using React Three Fiber, follow these steps:
-
Install the required packages:
npm install three @react-three/fiber
-
Create a basic 3D scene in your React component:
import React from 'react' import { Canvas } from '@react-three/fiber' function App() { return ( <Canvas> <ambientLight /> <mesh> <boxGeometry /> <meshStandardMaterial /> </mesh> </Canvas> ) } export default App
-
Run your React application and you should see a 3D cube rendered on the screen.
Competitor Comparisons
JavaScript 3D Library.
Pros of three.js
- Lower-level API providing more control and flexibility
- Wider ecosystem and community support
- Can be used with any JavaScript framework or vanilla JS
Cons of three.js
- Steeper learning curve for beginners
- More verbose code, requiring manual setup of scenes, cameras, and renderers
- Less integration with React's component-based architecture
Code Comparison
three.js:
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
react-three-fiber:
import { Canvas } from '@react-three/fiber'
function App() {
return (
<Canvas>
{/* Scene contents */}
</Canvas>
)
}
react-three-fiber provides a more declarative approach, abstracting away the boilerplate setup required in three.js. It allows for easier integration with React components and state management, making it more suitable for React-based projects. However, three.js offers more granular control and can be used in a wider range of JavaScript environments.
Babylon.js is a powerful, beautiful, simple, and open game and rendering engine packed into a friendly JavaScript framework.
Pros of Babylon.js
- More comprehensive and feature-rich 3D engine
- Better documentation and learning resources
- Larger community and ecosystem
Cons of Babylon.js
- Steeper learning curve for beginners
- Less integration with React ecosystem
- More verbose code for simple scenes
Code Comparison
Babylon.js:
const scene = new BABYLON.Scene(engine);
const camera = new BABYLON.FreeCamera("camera", new BABYLON.Vector3(0, 5, -10), scene);
const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: 2}, scene);
React Three Fiber:
function Scene() {
return (
<Canvas>
<perspectiveCamera position={[0, 5, -10]} />
<mesh>
<sphereGeometry args={[1, 32, 32]} />
<meshStandardMaterial />
</mesh>
</Canvas>
);
}
React Three Fiber provides a more declarative and React-like approach to creating 3D scenes, making it easier for React developers to integrate 3D graphics into their applications. However, Babylon.js offers a more powerful and feature-complete 3D engine with better performance for complex scenes and games. The choice between the two depends on the specific project requirements and the developer's familiarity with React and 3D graphics programming.
glTF – Runtime 3D Asset Delivery
Pros of glTF
- Industry-standard 3D file format with wide adoption and support
- Efficient, compact representation of 3D scenes and models
- Extensible format allowing for custom data and features
Cons of glTF
- Primarily a file format, not a rendering or interaction library
- Requires additional tools or libraries for rendering and manipulation
- Less focused on React integration compared to react-three-fiber
Code Comparison
glTF (JSON representation):
{
"asset": { "version": "2.0" },
"scene": 0,
"scenes": [{ "nodes": [0] }],
"nodes": [{ "mesh": 0 }],
"meshes": [{ "primitives": [{ "attributes": { "POSITION": 0 } }] }]
}
react-three-fiber:
function Scene() {
return (
<mesh>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="hotpink" />
</mesh>
)
}
Summary
glTF is a file format for 3D content, while react-three-fiber is a React renderer for Three.js. glTF excels in standardization and efficient 3D representation, but requires additional tools for rendering. react-three-fiber provides a more integrated solution for React developers working with 3D graphics, offering a declarative approach to creating and manipulating 3D scenes within React applications.
JavaScript game engine built on WebGL, WebGPU, WebXR and glTF
Pros of PlayCanvas Engine
- Complete game engine with built-in physics, audio, and animation systems
- Visual editor for scene creation and asset management
- Better performance for complex 3D applications and games
Cons of PlayCanvas Engine
- Steeper learning curve for developers new to game engines
- Less flexibility for integration with existing React applications
- More opinionated structure, which may limit customization options
Code Comparison
React Three Fiber:
function Box(props) {
const mesh = useRef()
return (
<mesh {...props} ref={mesh}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={'orange'} />
</mesh>
)
}
PlayCanvas Engine:
var entity = new pc.Entity();
entity.addComponent('model', {
type: 'box'
});
entity.addComponent('material', {
type: 'phong'
});
app.root.addChild(entity);
Summary
React Three Fiber is ideal for React developers looking to add 3D graphics to their web applications, offering a more familiar syntax and easier integration with existing React projects. PlayCanvas Engine, on the other hand, is better suited for full-fledged 3D game development, providing a comprehensive set of tools and features at the cost of a steeper learning curve and less flexibility for web application integration.
React component for Spline scenes.
Pros of react-spline
- Simplified workflow for importing and using 3D scenes created in Spline
- Easier integration of interactive 3D elements for designers and non-developers
- Automatic handling of scene loading and optimization
Cons of react-spline
- Limited to scenes created in Spline, less flexibility for custom 3D development
- Smaller community and ecosystem compared to react-three-fiber
- Potentially less performant for complex scenes or large-scale applications
Code Comparison
react-spline:
import Spline from '@splinetool/react-spline';
function App() {
return <Spline scene="https://prod.spline.design/example.splinecode" />;
}
react-three-fiber:
import { Canvas } from '@react-three/fiber';
import { Box } from '@react-three/drei';
function App() {
return (
<Canvas>
<Box position={[0, 0, 0]} />
</Canvas>
);
}
react-spline focuses on simplicity and ease of use for Spline-created scenes, while react-three-fiber offers more flexibility and control over custom 3D scenes. The choice between the two depends on the project's requirements, the team's expertise, and the desired level of customization.
✌️ A spring physics based React animation library
Pros of react-spring
- Focuses on general-purpose animations and transitions
- Easier to learn and implement for basic UI animations
- Smaller bundle size and lighter performance impact
Cons of react-spring
- Limited to 2D animations and transformations
- Lacks advanced 3D rendering capabilities
- Not optimized for complex, GPU-accelerated graphics
Code Comparison
react-spring:
import { useSpring, animated } from 'react-spring'
function AnimatedComponent() {
const props = useSpring({ opacity: 1, from: { opacity: 0 } })
return <animated.div style={props}>I will fade in</animated.div>
}
react-three-fiber:
import { Canvas, useFrame } from '@react-three/fiber'
import { useRef } from 'react'
function RotatingBox() {
const meshRef = useRef()
useFrame(() => (meshRef.current.rotation.x += 0.01))
return <mesh ref={meshRef}><boxGeometry /></mesh>
}
function Scene() {
return <Canvas><RotatingBox /></Canvas>
}
While react-spring excels in creating smooth, physics-based animations for UI elements, react-three-fiber is specifically designed for 3D rendering and complex WebGL-based graphics. react-spring is more accessible for general web development, whereas react-three-fiber offers powerful tools for creating immersive 3D experiences within React applications.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
@react-three/fiber
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
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:
- 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 Jouney, arguably the best learning resource, now includes a full R3F chapter
Ecosystem
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
– scene editor for react-three-fiberkoestlich
– UI component library for react-three-fiber
Usage Trend of the @react-three Family
Who is using Three-fiber
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
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.
Top Related Projects
JavaScript 3D Library.
Babylon.js is a powerful, beautiful, simple, and open game and rendering engine packed into a friendly JavaScript framework.
glTF – Runtime 3D Asset Delivery
JavaScript game engine built on WebGL, WebGPU, WebXR and glTF
React component for Spline scenes.
✌️ A spring physics based React animation library
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot