Using a pack in React Three Fiber
Load a pack GLB directly or use an included R3F component, with self-hosted Draco for compressed files.
On this page (6)
Pack GLBs work with useGLTF. Some bundles also include React Three Fiber components; check the pack page and ZIP rather than assuming components are present. You host the downloaded files in your own application.
Use an included component#
Copy the component and its matching GLB into your project. Keep the GLB at the URL used inside the component, or edit both its useGLTF and preload paths.
import { Canvas } from '@react-three/fiber'
import { Asset01 } from './components/Asset01'
export default function App() {
return (
<Canvas camera={{ position: [4, 3, 6] }}>
<ambientLight intensity={0.8} />
<directionalLight position={[5, 8, 5]} />
<Asset01 position={[0, 0, 0]} />
</Canvas>
)
}Included components vary. Some expose typed nodes and materials; others clone the loaded scene. Inspect the file you downloaded for its props, URL, and named objects.
Load a GLB directly#
You do not need an included component:
import React from 'react'
import { Clone, useGLTF } from '@react-three/drei'
export function AssetModel(props: Omit<React.ComponentProps<typeof Clone>, 'object'>) {
const { scene } = useGLTF('/models/asset.glb')
return <Clone object={scene} {...props} />
}
useGLTF.preload('/models/asset.glb')Clone is useful when the same cached GLB appears more than once. If you edit a component's materials or scene graph, clone the affected objects first when instances must remain independent.
Match the prop type to your React version#
Derive the prop type from Clone rather than from a JSX namespace. Omit<React.ComponentProps<typeof Clone>, 'object'> compiles on React 18 with R3F v8 and on React 19 with R3F v9, so you do not have to branch on either version.
The two common alternatives are version-specific:
JSX.IntrinsicElements['group']fails on React 19, because its@types/reactremoved the globalJSXnamespace. TypeScript reportsTS2503: Cannot find namespace 'JSX'.ThreeElements['group'], imported from@react-three/fiber, exists only in R3F v9 and does not resolve on v8.
Older included components were generated with JSX.IntrinsicElements['group'], so a buyer on React 19 may see TS2503 from a downloaded component. Change that component's prop type to the derived form above; the component body needs no other change. Newer bundles already ship the derived form.
Repointing the namespace to React.JSX.IntrinsicElements['group'] is not enough on React 19: it resolves the namespace and then surfaces a ref-variance mismatch (TS2322) when the group props spread into Clone.
Load a Draco file#
Current low-poly individual bundle GLBs are commonly uncompressed. Combined catalogs and some prebuilds are compressed. For a Draco file, copy compatible decoder files into your own public/draco/ directory and pass that path:
import { useGLTF } from '@react-three/drei'
export function CatalogPreview() {
const { scene } = useGLTF('/models/catalog.glb', '/draco/')
return <primitive object={scene} />
}
useGLTF.preload('/models/catalog.glb', '/draco/')If an included component loads a compressed GLB, update both its load and preload calls to use your decoder path. threejsassets does not provide a decoder or asset CDN.
Read a README's headline compression line as a description of the combined catalog, not of every file in the ZIP. Several packs open with a blanket "Draco-compressed glTF" summary while the individual GLBs they ship are uncompressed; the same READMEs name the catalog specifically as the joined and Draco-compressed file. Verify per file rather than configuring a decoder for the whole bundle.
Those READMEs also print a public CDN decoder path in their quick-start snippets. Self-host the decoder instead, so the decoder version and your Content Security Policy stay under your control.
The combined catalog is a joined inspection model, not a composed scene with independently placeable assets. Use individual GLBs for scene composition.
Work with nodes and materials#
When a generated type is included, it documents the exact named surface for that release:
nodescontains meshes, groups, or slot objects;materialscontains shared or named-zone materials; andanimationscontains clips when the GLB provides them.
Prebuild slots are declared in that nodes type as slot_<name>: THREE.Object3D, so with an included component you can reference a slot through nodes and let the compiler catch a renamed slot, instead of reaching for getObjectByName at runtime. See decoratable prebuilds & slots.
Those names are not universal across packs. Keep the downloaded component and README with the matching GLB.
Next steps#
- Using a pack in vanilla three.js — use
GLTFLoaderdirectly. - Individual GLBs vs the combined catalog — choose the right file.
- Configurator packs: swapping material zones — change named materials safely.
Ask us directly — we answer support mail ourselves.