From GLB to JSX: Integrating 3D Models into Your React App


In React, we can use tools like gltfjsx package to convert 3D models from GLB or GLTF formats into *.jsx components for rendering within a React application.
GLTF (GL Transmission Format): A JSON-based format for 3D scenes and models, including meshes, textures, and animations, designed for efficient web transmission as seperate files.
GLB: A compact, binary version of GLTF that includes all resources in a single file, ideal for efficient 3D content transfer and use in web applications.
To make it easier to understand, I'm going to use both GLB and GLTF files of the same model and explain how we can convert 3D files into JSX components in both cases
npm install three @types/three @react-three/fiber @react-three/drei glb on the browser (glb to jsx)3d model Merc Hovercar from Sketchfab and save the file inside the public > 3dModel folder. CLI to navigate to the 3dModel folder. Ideally, the 3dModel should be inside the public > 3dModel folder.cd .\public\3dModel\ jsx file and compressed version of the model (the textures will be converted to webp)npx gltfjsx free_merc_hovercar.glb --dracoThis command installs the
gltfjsxnpm package and converts theGLTFfile to[fileName]-transformed.glb
The
[fileName].jsxfile will also be generated inside the folder.
or run the following command if you are insideIf you don’t need to compress the texture, then remove the
--dracoflag.
gltf model foldernpx gltfjsx .\scene.gltf --dracoThis will only generate a
jsxfile inside the folder
import React, { useRef } from "react";
import { useGLTF } from "@react-three/drei";
export function Model(props) {
const { nodes, materials } = useGLTF("/free_merc_hovercar.glb");
return (
<group {...props} dispose={null}>
<group
position={[0.019, -0.066, -0.047]}
rotation={[-Math.PI / 2, 0, 0]}
scale={0.496}
>
<mesh
geometry={nodes.Plane006_0.geometry}
material={materials["Material.001"]}
/>
<mesh
geometry={nodes.Plane006_1.geometry}
material={materials.Material_light}
/>
<mesh
geometry={nodes.Plane_0.geometry}
material={materials.Plane_0}
position={[0, 0, -0.582]}
scale={[1.187, 2, 1]}
/>
</group>
</group>
);
}
useGLTF.preload("/free_merc_hovercar.glb"); export function FlyingCar(props)
Then move the *.jsx file to src>components>3dModel>FlyingCar.jsx 3dModel/free_merc_hovercar.glbimport React, { useRef } from "react";
import { useGLTF } from "@react-three/drei";
export function FlyingCar(props) {
const { nodes, materials } = useGLTF("3dModel/free_merc_hovercar.glb");
return (
<group {...props} dispose={null}>
<group
position={[0.019, -0.066, -0.047]}
rotation={[-Math.PI / 2, 0, 0]}
scale={0.496}
>
<mesh
geometry={nodes.Plane006_0.geometry}
material={materials["Material.001"]}
/>
<mesh
geometry={nodes.Plane006_1.geometry}
material={materials.Material_light}
/>
<mesh
geometry={nodes.Plane_0.geometry}
material={materials.Plane_0}
position={[0, 0, -0.582]}
scale={[1.187, 2, 1]}
/>
</group>
</group>
);
}
useGLTF.preload("3dModel/free_merc_hovercar.glb"); 3d model using react three fiber. Create a new route and page to display the 3d model. Now open the page file. In my case my page file is GlbModel.jsximport { Canvas } from "@react-three/fiber";
import { CameraControls, PerspectiveCamera } from "@react-three/drei";
function GlbModel() {
return (
<>
<title>GLB Model</title>
<main className="px-5">
<div className="border-2 h-[700px] my-5 rounded-lg">
<Canvas>
<PerspectiveCamera
makeDefault
fov={75}
position={[0, 0, 2]}
resolution={1024}
/>
<CameraControls />
<ambientLight intensity={0.5} />
</Canvas>
</div>
</main>
</>
);
}
export default GlbModel; 3D model. Since the 3D model may load more slowly and asynchronously compared to the page, we also need to import Suspense from React.import { Canvas } from "@react-three/fiber";
import { Suspense } from "react";
import { CameraControls, PerspectiveCamera } from "@react-three/drei";
import { FlyingCar } from "../components/3dModels/FlyingCar.jsx";
function GlbModel() {
return (
<>
<title>GLB Model</title>
<main className="px-5">
<div className="border-2 h-[700px] my-5 rounded-lg">
<Canvas>
<PerspectiveCamera
makeDefault
fov={75}
position={[0, 0, 2]}
resolution={1024}
/>
<CameraControls />
<ambientLight intensity={5} />
<Suspense>
<FlyingCar></FlyingCar>
</Suspense>
</Canvas>
</div>
</main>
</>
);
}
export default GlbModel; hdr image to improve the look even furthur.import { Canvas } from "@react-three/fiber";
import { Suspense } from "react";
import {
CameraControls,
PerspectiveCamera,
Environment,
} from "@react-three/drei";
import { FlyingCar } from "../components/3dModels/FlyingCar.jsx";
function GlbModel() {
return (
<>
<title>GLB Model</title>
<main className="px-5">
<div className="border-2 h-[700px] my-5 rounded-lg">
<Canvas>
<PerspectiveCamera
makeDefault
fov={75}
position={[0, 0, 2]}
resolution={1024}
/>
<CameraControls />
<ambientLight intensity={1} />
<Suspense>
<FlyingCar></FlyingCar>
</Suspense>
<Environment background={false} preset={"apartment"} />
</Canvas>
</div>
</main>
</>
);
}
export default GlbModel;If you are confuse about how the
hdrimage working, you can check the official documentation Basically somehdrare already provided in the@react-three/dreipackage and we can use those using the current preset likeapartment,city,forest,studioetc.
hdr image then you can store the hdr image on public > hdr > dry_field_01k.hdr and use the image like the following codeimport { Canvas } from "@react-three/fiber";
import { Suspense } from "react";
import {
CameraControls,
PerspectiveCamera,
Environment,
} from "@react-three/drei";
import { FlyingCar } from "../components/3dModels/FlyingCar.jsx";
function GlbModel() {
return (
<>
<title>GLB Model</title>
<main className="px-5">
<div className="border-2 h-[700px] my-5 rounded-lg">
<Canvas>
<PerspectiveCamera
makeDefault
fov={75}
position={[0, 0, 2]}
resolution={1024}
/>
<CameraControls />
<ambientLight intensity={1} />
<Suspense>
<FlyingCar></FlyingCar>
</Suspense>
<Environment
background={true}
files={["/hdr/dry_field_01k.hdr"]}
/>
</Canvas>
</div>
</main>
</>
);
}
export default GlbModel; Environment tag.import { Canvas } from "@react-three/fiber";
import { Suspense } from "react";
import {
CameraControls,
PerspectiveCamera,
Environment,
} from "@react-three/drei";
import { FlyingCar } from "../components/3dModels/FlyingCar.jsx";
function GlbModel() {
return (
<>
<title>GLB Model</title>
<main className="px-5">
<div className="border-2 h-[700px] my-5 rounded-lg">
<Canvas>
<PerspectiveCamera
makeDefault
fov={75}
position={[0, 0, 2]}
resolution={1024}
/>
<CameraControls />
<ambientLight intensity={1} />
<Suspense>
<FlyingCar></FlyingCar>
</Suspense>
<Environment
background={true}
files={["/hdr/dry_field_01k.hdr"]}
ground={{
height: 5, // Height of the camera that was used to create the env map (Default: 15)
radius: 120, // Radius of the world. (Default 60)
scale: 10, // Scale of the backside projected sphere that holds the env texture (Default: 1000)
}}
/>
</Canvas>
</div>
</main>
</>
);
}
export default GlbModel; 
Improve user experience in your React SPA by using client-side routing techniques instead of traditional anchor tags.

Understand side effects in React, why they are essential, and how to manage them using the useEffect hook. Learn with practical examples and tips.