Export Three.js Scene to GLTF Using GLTFExporter

This article explains how to use the GLTFExporter in Three.js to serialize an entire 3D scene and export it as a downloadable GLTF or GLB file. You will learn what the GLTFExporter is, how to import it into your project, and the step-by-step code required to convert your runtime 3D scene into a file that users can download directly from their web browser.

What is GLTFExporter?

GLTFExporter is an official helper class provided by the Three.js library. It allows you to export Three.js 3D objects, meshes, lights, cameras, animations, and entire scenes into the gTF (GL Transmission Format) standard.

GLTF is widely considered the “JPEG of 3D” because it is highly efficient, extensible, and universally supported across 3D engines, modeling software (like Blender), and web viewers. GLTFExporter can output either a text-based .gltf file (accompanied by external asset files or embedded data) or a self-contained, binary .glb file.

Step 1: Import GLTFExporter

Because the exporter is an addon, it is not included in the core Three.js package by default. You must import it separately from the examples folder.

import * as THREE from 'three';
import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js';

Step 2: Set Up the Export Function

To serialize your scene, you need to instantiate the GLTFExporter and call its .parse() method. This method takes your scene (or a specific 3D object), a callback function to handle the output, an error callback, and an optional configuration object.

Here is the basic structure of the export function:

function exportScene(sceneToExport) {
    const exporter = new GLTFExporter();

    const options = {
        binary: true, // Exports as a single .glb file instead of .gltf
        animations: sceneToExport.animations || [], // Include animations if present
        onlyVisible: true // Exclude hidden objects
    };

    exporter.parse(
        sceneToExport,
        function (result) {
            if (result instanceof ArrayBuffer) {
                // Handling binary (.glb) output
                saveArrayBuffer(result, 'scene.glb');
            } else {
                // Handling text-based (.gltf) output
                const output = JSON.stringify(result, null, 2);
                saveString(output, 'scene.gltf');
            }
        },
        function (error) {
            console.error('An error occurred during GLTF export:', error);
        },
        options
    );
}

Step 3: Trigger the Browser Download

To save the serialized data onto the user’s local machine, you need to generate a temporary link, attach the exported data as a Blob, programmatically click the link, and then discard it.

Here are the helper functions to handle both string output (JSON .gltf) and array buffer output (binary .glb):

// Trigger download for text-based .gltf files
function saveString(text, filename) {
    save(new Blob([text], { type: 'text/plain' }), filename);
}

// Trigger download for binary .glb files
function saveArrayBuffer(buffer, filename) {
    save(new Blob([buffer], { type: 'application/octet-stream' }), filename);
}

// Core helper function to force a browser download
function save(blob, filename) {
    const link = document.createElement('a');
    link.style.display = 'none';
    document.body.appendChild(link); // Required for Firefox

    link.href = URL.createObjectURL(blob);
    link.download = filename;
    link.click();

    // Clean up
    document.body.removeChild(link);
    URL.revokeObjectURL(link.href);
}

Step 4: Hooking It Up to a UI Element

You can trigger the entire process by binding the export function to a simple HTML button:

<button id="export-btn">Download 3D Scene</button>
document.getElementById('export-btn').addEventListener('click', () => {
    // Assuming 'scene' is your active Three.js Scene instance
    exportScene(scene);
});