dash-model-viewer — interactive 3D models and AR for Dash. Google's model-viewer vendored in the wheel: no CDN, works offline. By Pip Install Python.

dash-model-viewer — interactive 3D models and AR for Dash

dash-model-viewer — embed interactive 3D models directly into your Dash applications with Augmented Reality (AR) support. By Pip Install Python.

A Dash wrapper around Google's model-viewer. Drag the model above — then note that reading its camera, its dimensions, or a click on it takes a normal Dash callback and no JavaScript at all.

pip install dash-model-viewer
from dash import Dash, html
import dash_model_viewer as dmv

app = Dash(__name__)
app.layout = html.Div([
    dmv.ModelViewer(
        id="viewer",
        src="/assets/astronaut.glb",
        alt="A 3D model of an astronaut",
        style={"width": "100%", "height": "480px"},
    )
])

That is the whole setup. Importing the package installs the runtime.


What is different in 1.0.0

This release is a rebuild, and it fixes two things that had been broken for the package's entire published life.

AR actually works out of the box

ar_modes used to default to "basic_annotations scene-viewer quick-look". basic_annotations is not an AR mode — it was the name of a folder in the repository, copy-pasted into the default. webxr was therefore missing, so in-page WebXR AR never ran unless you happened to override the prop. Nothing errored; the flagship feature was just quietly degraded everywhere.

The default is now "webxr scene-viewer quick-look", and the test suite asserts it. → Augmented reality

Events reach Python

0.0.1 had no output props. Its single setProps call was commented out, so nothing the model did could reach your callbacks. Anything interactive needed a JavaScript file in assets/ and a clientside_callback to reach it.

The canonical camera-presets example was 230 lines because of that. It is now 47 lines of Python, with no JavaScript. → Camera and views

PropUpdates when
camerathe user moves the camera (debounced, echo-suppressed)
model_stateloading, loaded, failed
model_infoon load — dimensions in metres, variants, animations
ar_status / ar_trackingan AR session changes state
scene_pointthe model is clicked, with pick_on_click=True
Slot.n_clicksa hotspot is clicked

The bundle ships in the wheel

model-viewer used to be fetched at runtime from a hard-coded ajax.googleapis.com URL pinned to 3.5.0 — not a declared dependency, not pinnable by you, and unavailable offline, behind a corporate egress proxy, or under a strict script-src Content-Security-Policy.

Version 4.3.1 is now vendored inside the package and injected by a Dash hook. It costs about 1 MB per page, which is a real number and is stated plainly on the quick start rather than buried. configure(use_cdn=...) opts back out.


Full upstream parity, permanently

<model-viewer> has ~70 attributes and gains more each release. This package names about twenty and gives you two escape hatches that reach all of the rest — including attributes that do not exist yet:

dmv.ModelViewer(
    id="viewer", src=..., alt=...,
    mv_environment_image="neutral",          # -> environment-image
    attributes={"orientation": "0deg 0deg 15deg"},
)

No regeneration, no release, no waiting. → Attributes and parity


Where to go next

PageWhat it covers
Quick startInstall, first viewer, and why the script order matters
Events and callbacksEvery output prop, and camera_change_debounce
Camera and viewsPresets, flight, framing an unknown model
Slots and hotspotsAnchoring any Dash component to the geometry
Attributes and parityattributes and mv_*
Augmented realityThe three AR modes, and the fixed default
Model switchingRuntime src swaps and GLTF variants
Scene DirectorGenerative. Describe a shot; Claude stages it, grounded in the model's measured geometry
Generative 3D artGenerative. Describe a sculpture; get a real .glb built from primitives
Image to 3DGenerative. Upload a picture; Claude reads it and code carves a relief
BenchmarkOne prompt, several models or settings, sculptures side by side
API referenceEvery prop, every payload
Migrating from 0.0.1Prop-by-prop map

Credits

Built on Google's model-viewer (Apache-2.0), vendored at 4.3.1. Demo models are Google's own model-viewer shared assets and the Khronos Group's glTF Sample Assets. The CC BY 4.0 models require attribution, so: Materials Variants Shoe © 2021 Shopify; Glam Velvet Sofa © 2021 Wayfair, LLC (Eric Chadwick); Glass Hurricane Candle Holder © 2021 Wayfair, LLC (Eric Chadwick). Sheen Chair (© 2020 Wayfair, LLC) and Scattering Skull (© 2025 Vladimir Petkovic) are CC0 1.0.

Source on GitHub · PyPI

Note for AI agents: This is the static, prerendered view of an interactive Dash application served because we detected a non-JS user agent. Full prose docs: