GLB Model Viewer embeds binary glTF (.glb) 3D models directly in your MyST
Markdown. It renders a Z-up scene with an X-Y ground reference plane at Z=0,
lets readers orbit / pan / zoom, browse the metadata embedded in the file, and
jump between author-defined view presets.
🧭 Z-up scene with a radial ground reference plane and colored axes
🗂 Metadata tray — interactive, collapsible tree of the file’s
asset, extensions,extras, names and counts🎥 View presets + snapshot — save named camera/parameter views; capture the current view as a pasteable preset
🌗 Light / dark theming and an orientation override for non-Y-up exports
📦 DRACO-compressed geometry supported
Live demo¶
Duck — © 2006 Sony Computer Entertainment Inc., distributed under the SCEA Shared Source License 1.0, via the Khronos glTF Sample Assets.
“Littlest Tokyo” by Glen Fox (glenatron). Licensed under CC BY 4.0 (Creative Commons Attribution 4.0 International)
Original model: https://
Installation¶
Download the widget bundle and reference it from your MyST project:
During development use the local path (./dist/glb-model-viewer.js); in
published or cross-repo articles use the CDN URL where the file is hosted.
Usage¶
:::{anywidget} ./dist/glb-model-viewer.js
{
"src": "https://example.com/model.glb"
}
:::Provide either a src URL or inline base64 data.
Props¶
| Field | Type | Default | Description |
|---|---|---|---|
src | string | "" | URL to a .glb file (must be CORS-accessible). One of src/data required. |
data | string | "" | Base64-encoded .glb bytes (takes precedence over src). |
theme | string | "light" | "light" or "dark" — UI chrome + scene defaults. Toggleable in-widget. |
up_axis | string | "y" | Source up-axis rotated to world +Z: "y" (glTF default), "z", or "x". |
controls_mode | string | "freeform" | "freeform" or "rotate-pan" (Shift+drag pans along the ground plane). |
presets | array | [] | List of saved-view objects (see below); the first is applied on load. |
background | string | "" | Optional CSS color overriding the theme’s scene background. |
show_grid | boolean | true | Show the X-Y reference plane, grid, and axes at Z=0. |
auto_rotate | boolean | false | Slowly orbit the camera. |
tray_open | boolean | false | Open the metadata tray on load. |
Presets¶
Each entry in presets becomes a selectable button (labelled by its title)
and may carry any of the props above plus a camera:
{
"title": "Hero",
"theme": "dark",
"auto_rotate": false,
"camera": { "position": [2.27, -2.84, 1.99], "target": [0, 0, 0.77] }
}The 📷 snapshot toolbar button captures the current view as exactly this
object — copy it from the tray into your presets list and give it a title.
The first preset is applied on load; moving the view or toggling a control
deselects the active preset.
Variant examples¶
Dark theme, metadata open:
Rotate-pan controls with view presets:
“Littlest Tokyo” by Glen Fox (glenatron).
How it works¶
The widget is an anywidget front-end module bundling
Three.js. It loads the .glb with GLTFLoader (DRACO
decoding via a CDN-hosted decoder), wraps the model in a Z-up world (glTF is
Y-up, so it is rotated +90° about X), auto-frames it on the ground plane, and
reads the embedded metadata from the parsed glTF JSON for the tray. All
rendering and interaction run client-side, so it works in static MyST sites with
no live kernel.
Browser support¶
Targets modern evergreen browsers with WebGL2. The DRACO decoder is fetched on
demand from https://www.gstatic.com/draco/, so DRACO-compressed models need
network access to that CDN.
Source¶
Built from the glb-viewer anywidget project. The distributable bundle is
dist/glb-model-viewer.js.
Further reading¶
Copyright © 2026 Purves.