React Three Fiber: three.js expressed as JSX, pinned to your React major version
🇨🇭 A React renderer for Three.js
At a glance
- What is it?
- A close look at @react-three/fiber, the pmndrs React renderer for three.js: how tags map to three.js objects, how the render loop hook works, what the React version pairing and the React Native path demand, and where the WebGPU first v10 alpha stands.
- Who is it for?
- Use @react-three/fiber if your team already works in React and is ready to learn three.js concepts directly, because every JSX tag is a three.js object and nothing is abstracted away. Skip it if you want an engine that hides scenes, cameras and materials from you.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 24 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 12, 2026, and from our analysis. They are not legal advice.
Star history
- pmndrs/react-three-fiber33,680 ★ · +1,404
| Repository | 2026-09-13 | 2026-11-12 |
|---|---|---|
| pmndrs/react-three-fiber | 32.3k | 33.7k |
1,404 Stars in the last 60 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
Every JSX tag is a three.js constructor call
react-three-fiber, published on npm as @react-three/fiber, is a React renderer for three.js in the same sense that react-dom renders to the browser DOM and react-native renders to native views. Instead of calling constructors and attaching objects to a scene graph by hand, you describe the scene as reusable, self-contained components that react to state and handle interaction.
The mapping is direct. `<mesh />` turns into `new THREE.Mesh()` at runtime, and the project states that all three.js exports are native to three-fiber. That is why its own onboarding tells you to look up elements such as mesh and ambientLight in the three.js documentation rather than in a separate fiber catalog.
This design shapes how upgrades work. Because the library only expresses three.js in JSX, a feature that a new three.js release adds, removes or changes reaches your code without waiting for a fiber release. The same path carries breaking changes: when three.js renames or drops something, your JSX sees it immediately, since there is no translation layer in between to absorb the change.
Each fiber major is pinned to one React major
The install line pulls three.js and its type definitions alongside the renderer, so you choose the three version yourself rather than receiving one bundled inside fiber:
npm install three @types/three @react-three/fiberThe catch sits in a warning right under that command. Three-fiber is a React renderer, and like react-dom or react-native it must pair with a specific major version of React: @react-three/fiber@8 pairs with react@18, and @react-three/fiber@9 pairs with react@19.
The consequence for an existing app is that React and fiber cannot be upgraded independently. A project still on React 18 has to stay on fiber 8, and moving to React 19 means moving to fiber 9 in the same change. If you install the latest fiber into a React 18 codebase without checking, you end up with a renderer built for a React version you are not running. Treat the two packages as one upgrade unit and check both majors in package.json before you add anything else built on fiber.
useFrame subscribes a component to the render loop
The canonical example is a Box component that holds its own state, reacts to input and participates in the render loop. It imports the two pieces it needs from the package:
import { Canvas, useFrame } from '@react-three/fiber'Inside Box, a `useRef` gives direct access to the underlying THREE.Mesh object. Two `useState` hooks track hovered and clicked. The line `useFrame((state, delta) => (ref.current.rotation.x += delta))` registers a callback that runs every frame and rotates the mesh on its x axis by the frame delta. The returned mesh sets `scale={clicked ? 1.5 : 1}` and wires `onClick` and `onPointerOver` handlers, so pointer events are props like any other React event.
Note the split: per frame motion is written straight to the mesh through the ref, while discrete changes such as a click go through React state. The project claims there is no overhead because components render outside of React, and that it outperforms three.js at scale thanks to React scheduling. Those are the maintainers' own statements, and the FAQ answer gives no figures to check them against, so measure your own scene before relying on them.
TypeScript props come from ThreeElements and @types/three
The repository is written in TypeScript, and the typed variant of the Box example adds one dependency on top of the main install:
npm install @types/threeThe typed component imports `* as THREE from 'three'` for the object types and pulls `ThreeElements` from @react-three/fiber next to `Canvas` and `useFrame`. Props are typed as `ThreeElements['mesh']`, which means a custom Box accepts the same props a plain mesh element would, and spreading `{...props}` onto the inner mesh stays type safe. The ref is declared as `useRef<THREE.Mesh>(null!)`, so `ref.current.rotation` is known to exist inside the useFrame callback without extra null checks.
The practical effect is that type coverage for scene objects comes from @types/three, not from fiber itself. If @types/three lags behind or mismatches the three version you installed, the types you see in your editor will describe a different three.js than the one running in the browser. Keep the two packages on matching versions. A live TypeScript sandbox is linked from the README for comparison.
The native entry point needs Metro told about model and texture files
React Native support ships in the same package under a separate import path, `@react-three/fiber/native`, which exports its own `Canvas` and `useFrame`. The Box component written against it is the same as the web one apart from that import. The documented route uses Expo:
# 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 startTwo things in that recipe need care. First, the example states that it relies on React 18, yet it installs the `beta` tag of fiber and the `rc` tag of React. Given the strict major pairing, copying it verbatim into a new project gives you prerelease packages whose versions you have not chosen; check which fiber and React tags actually match before running it. Second, if you load files with `useLoader` or Drei helpers like `useGLTF` and `useTexture`, the Metro bundler may need to be told about those asset types:
// metro.config.js
module.exports = {
resolver: {
sourceExts: ['js', 'jsx', 'json', 'ts', 'tsx', 'cjs'],
assetExts: ['glb', 'png', 'jpg'],
},
}That list covers glb, png and jpg. Any other format you load has to be added to `assetExts` yourself.
No limitations also means no shortcut past three.js
Asked whether it has limitations, the project answers: none, everything that works in three.js works here without exception. Read the other way round, that answer says fiber adds nothing three.js cannot do and hides nothing three.js requires you to understand. Scenes, cameras, meshes, geometries and materials are all still yours to manage, only written as JSX.
The onboarding is blunt about this. You need to be versed in both React and three.js before starting. For React, it points to the official React docs and especially the hooks reference. For three.js, it asks you to get a basic grasp from the three.js manual, to know what a scene, camera, mesh, geometry and material are before forking the demo, and then to change values while browsing the fiber API at docs.pmnd.rs. It also recommends the Discover Threejs tips and tricks chapter and Bruno Simon's Threejs Journey, which now has a full R3F chapter.
The consequence for teams is two learning curves at once. A React developer with no 3D background will not be shielded from three.js concepts, and a three.js developer new to hooks will hit React's rules about refs and state. If you were hoping fiber would act as a higher level engine, it is not one.
Drei, gltfjsx and the other helpers are separate packages
The core package stays close to raw three.js, and most convenience lives elsewhere in the pmndrs ecosystem. The project lists `@react-three/drei` for helpers, describing it as an ecosystem in itself; `@react-three/gltfjsx`, which turns GLTF files into JSX components; `@react-three/postprocessing` for post-processing effects; `@react-three/uikit` for WebGL rendered UI components; and `@react-three/test-renderer`, which lives inside this repository under packages/test-renderer.
This split matters when you read tutorials. Hooks such as `useGLTF` and `useTexture` are Drei abstractions, not part of @react-three/fiber, so code that uses them fails until Drei is added as its own dependency. Drei is developed in its own repository at github.com/pmndrs/drei, so its install instructions and version pairing come from there rather than from the fiber install line.
The upside is that the renderer itself stays small in scope. The downside is that a typical project ends up assembling several pmndrs packages, each with its own release cadence, and each one has to agree with the fiber major you picked for your React version.
v10 is an alpha that puts WebGPU first, while v9 keeps shipping
The repository is not archived, and its last push landed on 2026-10-02. Releases are still arriving on two tracks. The stable line published v9.8.1 on 2026-09-24 and v9.8.2 on 2026-10-15. In parallel, v10.0.0-alpha.6 came out on 2026-10-17 under the title Going WebGPU First.
For anyone searching for fiber and WebGPU, that title is the signal: WebGPU is where the next major is headed, and it is still in alpha. An alpha tag carries no stability promise, so production apps belong on 9.x for now, and any move to 10 should start with that release's notes rather than assumptions carried over from 9.
Contributors meet a Yarn workspaces monorepo covering `packages/*` and an `example` app. Packages are built with preconstruct, versions and publishing go through changesets, tests run on Jest with coverage, and typechecking uses `tsc` in strict mode. The postinstall step runs `preconstruct dev` and then a `patch-react-reconciler` script that runs a Vite build, so a fresh clone does real work during install before anything else runs.
Editorial conclusion
Use @react-three/fiber if your team already works in React and is ready to learn three.js concepts directly, because every JSX tag is a three.js object and nothing is abstracted away. Skip it if you want an engine that hides scenes, cameras and materials from you. Before installing, confirm that your React major matches the fiber major (fiber 8 with React 18, fiber 9 with React 19), and keep the v10 alpha out of production until it leaves alpha.
Frequently asked questions
What is React Three Fiber used for?
React Three Fiber is a React renderer for three.js. It lets you build 3D scenes declaratively from reusable components that react to state, handle interaction and take part in the render loop.
Is React Three Fiber compatible with React 19?
Yes, through its version 9 line: @react-three/fiber@9 pairs with react@19, while @react-three/fiber@8 pairs with react@18. The fiber major has to match your React major.
How do you install React Three Fiber?
Install three.js, its types and the renderer together with npm install three @types/three @react-three/fiber, and make sure the fiber major matches your React major.
Is React Three Fiber free?
Yes. The pmndrs/react-three-fiber repository is released under the MIT license.
Does React Three Fiber support WebGPU?
WebGPU is the focus of the next major: v10.0.0-alpha.6, released on 2026-10-17, is titled Going WebGPU First. It is an alpha, while the stable line is v9.8.2.
Official sources
Where developers are discussing it
Posts on Hacker News, dev.to and Lobsters that link to this repository, found by our scan of those communities. 1 in the last 30 days; newest first.
- This Week In React #302 : Next.js, React Router, DevTools, Security | RN 0.88, Expo 58, Navigation | TypeScript, PHP, CrUXdev.to · Oct 23, 2026 · 2 points · 0 comments
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/pmndrs-react-three-fiber)Star history chart for your README
[](https://hysenlabs.com/projects/pmndrs-react-three-fiber)Was this useful?