Storing Inline Base64 Data URIs in glTF

This article provides an overview of how the glTF (GL Transmission Format) 3D asset specification uses inline base64-encoded Data URIs to create self-contained files. By embedding binary buffers and image textures directly into the primary JSON structure via the Data URI scheme, developers can distribute complete 3D models as single text files. The following sections explain the underlying syntax, implementation within buffers and textures, practical benefits, and the technical trade-offs associated with this approach.

The Data URI Scheme in glTF

The glTF standard relies on the standard RFC 2397 Data URI scheme to embed resources that would otherwise exist as external files. Instead of pointing to an external path, the resource locator holds the data payload itself using the following structure:

data:[<mediatype>][;base64],<data>

When a glTF parser encounters a string matching this pattern in a URI field, it bypasses network requests or local filesystem reads, immediately decoding the base64-encoded text into memory.

Embedding Binary Buffers

A standard glTF file separates structural scene descriptions (JSON) from raw binary data, such as vertex positions, normals, texture coordinates, and animation keyframes. This binary data typically lives in a companion .bin file referenced within the buffers array.

To inline this data, the uri property of a buffer object is populated with a base64 Data URI instead of a file path:

{
  "buffers": [
    {
      "byteLength": 1024,
      "uri": "data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAA..."
    }
  ]
}

The media type for raw buffers is typically set to application/octet-stream or application/gltf-buffer. Downstream elements such as bufferViews and accessors reference this buffer index normally, completely agnostic to whether the underlying bytes were fetched over a network or decoded from text.

Embedding Textures and Images

Textures can also be embedded directly into the glTF JSON. The images array elements support Data URIs within their uri properties:

{
  "images": [
    {
      "mimeType": "image/png",
      "uri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
    }
  ]
}

When decoded, the image data is passed directly to the client's texture loader, eliminating the need to bundle separate JPEG, PNG, or WebP files alongside the model.

Advantages of Inline Data URIs

  • Single-File Portability: Eliminates the complexity of managing multi-file assets (JSON + .bin + images), preventing broken paths when files are moved or shared.
  • Network Simplicity: Reduces HTTP request overhead by bundling all geometry and textures into a single payload, which can be useful when transferring models across web APIs or embedding them directly into database records.
  • CORS Mitigation: Avoids cross-origin resource sharing (CORS) security issues that can arise when a viewer fetches separate .bin or texture files hosted across different domains.

Performance Considerations and Trade-offs

While convenient, embedding resources as base64 Data URIs introduces measurable performance penalties:

  • File Size Overhead: Base64 encoding increases data size by approximately 33% compared to raw binary data.
  • CPU and Memory Overhead: The client must parse large strings and execute base64 decoding routines before passing data to the GPU. This consumes extra main-thread CPU cycles and causes temporary memory spikes during loading.
  • Alternative Approaches: For production environments requiring single-file distribution without the size and decoding penalties of base64 Data URIs, the binary glTF format (.glb) is generally preferred. GLB packages the JSON and binary data into a single binary container, avoiding the 33% size inflation entirely.