Dashboard →

Framework loaders

The compat report says a runtime needs a decoder; these packages configure it and load the asset.

The gpu and mobile presets use meshopt geometry and KTX2 textures, and ad-hoc specs can use Draco. three.js and Babylon.js load them once they know where the decoders are. The CDN serves the same decoder files the viewer uses under /_/decoders; @glboost/three and @glboost/babylon point the engines there, build the asset URLs, and wait while a variant is still being optimized (the CDN answers 202 until then, and serves a ready fallback variant when one exists).

three.js

npm install @glboost/three three
import { createGLTFLoader, loadAsset } from '@glboost/three';

const loader = createGLTFLoader({ renderer });      // KTX2 support is detected on your renderer
const gltf = await loadAsset(loader, 'abcdefghjkmn', {
  preset: 'gpu',
  onFallback: ({ served }) => console.log('serving', served, 'until gpu is ready'),
});
scene.add(gltf.scene);

// or the classic API: the loader retries a 202 and reports fallbacks the same way
loader.load(assetUrl('abcdefghjkmn', { preset: 'gpu' }), (gltf) => scene.add(gltf.scene));

createGLTFLoader returns a GLTFLoader subclass with Draco at /_/decoders/draco/, KTX2 at /_/decoders/basis/, and the meshopt decoder from the meshoptimizer package; configureLoader does the same on a loader you already have. Options: base, draco, ktx2, meshopt, retry (default every 5 s, 60 times), onFallback.

react-three-fiber

import { Suspense } from 'react';
import { Canvas } from '@react-three/fiber';
import { GLBoostModel, useGLBoost } from '@glboost/three/r3f';

function Chair() {
  const { scene } = useGLBoost('abcdefghjkmn', { preset: 'gpu' });
  return <primitive object={scene} />;
}

export default () => (
  <Canvas>
    <Suspense fallback={null}>
      <Chair />
      <GLBoostModel asset="k7m2p9q4r1s8" position={[1, 0, 0]} />
    </Suspense>
  </Canvas>
);

useGLBoost is useLoader with the GLBoost loader configured on the canvas's renderer; useGLBoost.preload and useGLBoost.clear mirror useLoader's. GLBoostModel renders the scene inside a group and passes group props through.

Babylon.js

npm install @glboost/babylon @babylonjs/core @babylonjs/loaders
import { configureGLBoost, loadGLBoostAsset } from '@glboost/babylon';

configureGLBoost();     // once: Draco and meshopt decoders from cdn.glboost.com

const container = await loadGLBoostAsset(scene, 'abcdefghjkmn', { preset: 'gpu' });
container.addAllToScene();

Babylon's KTX2 transcoders are not the files GLBoost hosts, so KTX2 keeps Babylon's defaults unless you host them and pass configureGLBoost({ ktx2: { urls } }).

Decoders on the CDN

/_/decoders/draco/
draco_wasm_wrapper.js, draco_decoder.wasm, draco_decoder.js (three.js and Babylon.js Draco paths)
/_/decoders/basis/
basis_transcoder.js, basis_transcoder.wasm (three.js KTX2Loader transcoder path)
/_/decoders/meshopt_decoder.js
The meshopt decoder as a classic script (Babylon.js); three.js takes the module from meshoptimizer

All of /_/ answers CORS *. The files come from the viewer build, so their versions match what the embed uses; Draco and Basis builds are stable across three releases, which is why the packages accept three >= 0.160.

202, fallbacks, and private assets

Right after an upload the CDN answers 202 for a variant that is still optimizing; both packages wait and retry (retry.intervalMs, retry.attempts) and throw GLBoostNotReadyError when it never arrives. When another variant of the version is ready meanwhile, the CDN serves it with x-glboost-variant: fallback and the packages call onFallback with the served spec, so you can reload once the requested one exists. Private assets and signing-required projects need a signed URL: mint it on your server with signUrl from the SDK or signedAssetUrl (the signing key never ships to a browser) and pass it as url. The grammar behind these URLs is on URLs and presets.