Loading Models

threejs model

Building everything from basic shapes (boxes, spheres, cylinders) works fine for simple things. But what if you want a detailed character, a car, a spaceship, or a realistic environment? You could spend days or weeks trying to code that with BufferGeometry — or you could just download a model and load it in a few lines of code.

Think of it like this: you can draw a stick figure with a pen (basic shapes), or you can grab a statue off the shelf (a model). Both have their place.

what format to use

Three.js supports many 3D model formats, but GLTF (.gltf or .glb) is the best choice for the web. It's lightweight, loads fast, and supports everything you'll need — geometry, materials, animations, and even cameras.

  • .gltf — a text-based format (JSON), comes with separate texture files
  • .glb — a single binary file, everything bundled together

☝️ tip: Use .glb if you want one file to move around. It's the most common format you'll find on sites like Sketchfab and Poly Pizza.

loading a model with GLTFLoader

You'll need to import the GLTFLoader from Three.js's examples, then load your file:

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

const loader = new GLTFLoader();

loader.load(
    '/models/scene.gltf', // path to your model file
    (gltf) => {
        // called when loading succeeds
        const model = gltf.scene;
        scene.add(model);
    },
    (xhr) => {
        // called during loading (progress)
        const percent = (xhr.loaded / xhr.total) * 100;
        console.log(`${Math.round(percent)}% loaded`);
    },
    (error) => {
        // called if something goes wrong
        console.error('Error loading model:', error);
    },
);

Let's break down those four arguments:

Argument What it does
path The URL or file path to your .gltf or .glb file
onLoad Runs when the file is loaded — add the model to your scene
onProgress Runs repeatedly as the file downloads (optional)
onError Runs if loading fails — helpful for debugging

loading multiple models from the same project

Here's a real example — loading two different .glb files and scaling/positioning them differently:

const loader = new GLTFLoader();

// Load a character model
loader.load(
    '/threejayess/models/computerman.glb',
    (gltf) => {
        const model = gltf.scene;
        model.scale.multiplyScalar(0.2); // make it smaller
        scene.add(model);
    },
    undefined, // skip progress
    (error) => console.error('Error:', error),
);

// Load another model
loader.load('/threejayess/models/gunner.glb', (gltf) => {
    const model = gltf.scene;
    model.position.set(0, 0.2, 0); // sit on the ground
    model.scale.multiplyScalar(0.8);
    scene.add(model);
});

cleaning up when you remove a model

If you need to remove a model (like when navigating away from a page), make sure to properly dispose of it:

let model = null;

// When loading, save the reference
loader.load('/models/scene.gltf', (gltf) => {
    model = gltf.scene;
    scene.add(model);
});

// When cleaning up
function cleanup() {
    if (model) {
        scene.remove(model);
        model = null;
    }
}

where to find free models

a few things to keep in mind

  • File size matters — a 50MB model will take a while to load. Compress textures and decimate geometry to keep things small.
  • Models often need scaling — a model from Sketchfab might be huge compared to your scene. Adjust with model.scale.set(...).
  • Animations come with the model — loading a .glb file can also load animations. See Animation Systems for how to play them.
  • CORS can block loading — if you're loading from a different domain, the server needs to allow it. Local files work fine.