# khronosgroup/gltf-sample-viewer architecture

> Architecture diagram of the GitHub repository khronosgroup/gltf-sample-viewer, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-12). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/khronosgroup/gltf-sample-viewer
- Repository: https://github.com/khronosgroup/gltf-sample-viewer

## Overview

1. **Project type and runtime**
   - This is a **client-side web application** for viewing glTF 2.0 assets in the browser.
   - It runs entirely in the browser on **WebGL 2.0**, with no application backend in this repo.

2. **Top-level composition**
   - `index.html` is the shell page.
   - `main.js` at the repo root is the browser entry point.
   - `src/main.js` appears to be the real application bootstrap, with `main.js` likely forwarding into the source build pipeline.
   - The app is split into a **UI layer**, a **state/logic layer**, and a **renderer integration layer**.

3. **Rendering subsystem**
   - The actual 3D rendering is delegated to the **`glTF-Sample-Renderer` submodule**.
   - That submodule is the core dependency for loading and drawing models, materials, animations, lighting, compression formats, and extensions.
   - This repo mostly wraps and configures that renderer rather than implementing its own rendering engine.

4. **UI subsystem**
   - `src/ui/ui.js` and `src/ui/sass.scss` define the in-browser control surface.
   - The UI provides model selection, drag-and-drop loading, lighting/tone mapping controls, animation toggles, material variants, validator feedback, stats, downloads, and debug channels.
   - Styling is isolated in Sass, which suggests the viewer UI is a distinct presentation layer over the renderer.

5. **State and behavior subsystem**
   - `src/logic/uimodel.js` is the central state/interaction model for the viewer.
   - It likely mediates between user actions and renderer behavior: selected model, camera state, animation enablement, material variant choice, extension/debug toggles, and UI visibility.
   - This is the main boundary between UI events and rendering configuration.

6. **Asset/model path resolution**
   - `src/model_path_provider.js` is a dedicated helper for resolving model and asset URLs.
   - Given the README’s support for sample assets, custom URLs, and drag-and-drop files, this module likely abstracts where model content comes from and how it is addressed.
   - It forms an important boundary between the viewer and external asset sources.

7. **Input and data-flow path**
   - User inputs come from three main sources: **UI controls**, **drag-and-drop files**, and **URL parameters**.
   - Those inputs flow into the UI model/state layer, which then configures the renderer and loads the appropriate glTF/HDR resources.
   - The app also supports externally hosted content through URL parameters such as `model`, camera offsets, and `noUI`.

8. **Supported content and external dependencies**
   - The viewer is designed around the glTF ecosystem and supports many Khronos/Vendor extensions, including compression, lighting, material variants, basis textures, and mesh instancing.
   - It also supports HDR environment maps, so the rendering pipeline handles both model content and scene lighting inputs.
   - Validation support is integrated into the UX, implying the viewer can surface glTF validation results alongside rendering.

9. **Build and packaging pipeline**
   - `rollup.config.js` drives bundling for the browser.
   - `package.json` plus `package-lock.json` define the frontend toolchain and dependencies.
   - The output is a static `dist` directory, consistent with deployment to ordinary static hosting.

10. **Deployment and hosting**
   - The GitHub Actions workflow in `.github/workflows/Publish_to_Github_Pages.yml` publishes the built app to **GitHub Pages**.
   - This repository therefore has a simple deploy model: build in CI, publish static assets, serve directly from a CDN/static host.

11. **Repository organization**
   - `assets/` contains figures, images, and UI resources used by the viewer and documentation.
   - `glTF-Sample-Renderer/` is intentionally separated as vendored source via git submodule.
   - The repo is focused on the viewer wrapper, while the renderer engine remains upstreamed.

12. **Architecture summary for diagramming**
   - A good diagram would show: **browser shell/index → app bootstrap → UI/state layer → sample renderer submodule → WebGL2 canvas**, with side inputs from **URL parameters**, **drag-and-drop files**, and **model path resolution**.
   - A separate deployment lane should show **Rollup build → dist → GitHub Pages**.

Main entry points: [`src/logic/uimodel.js`](https://github.com/khronosgroup/gltf-sample-viewer/blob/main/src/logic/uimodel.js) (UI model), [`glTF-Sample-Renderer`](https://github.com/khronosgroup/gltf-sample-viewer/tree/main/glTF-Sample-Renderer) (Sample Renderer), [`src/main.js`](https://github.com/khronosgroup/gltf-sample-viewer/blob/main/src/main.js) (App bootstrap), [`src/ui/ui.js`](https://github.com/khronosgroup/gltf-sample-viewer/blob/main/src/ui/ui.js) (UI controls)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["Viewer app"]
  node_index_html["index.html<br/>shell page<br/>[index.html]"]
  node_root_entry["main.js<br/>browser entry<br/>[main.js]"]
  node_app_bootstrap["App bootstrap<br/>startup<br/>[main.js]"]
  node_ui_layer["UI controls<br/>presentation<br/>[ui.js]"]
  node_ui_styles["UI styles<br/>sass<br/>[sass.scss]"]
  node_viewer_state["UI model<br/>state model<br/>[uimodel.js]"]
  node_path_provider["Path provider<br/>asset resolver"]
  node_url_inputs(("URL params<br/>input source"))
  node_drop_inputs(("Drag and drop<br/>input source"))
  node_webgl_runtime(("WebGL 2.0<br/>browser runtime"))
  node_scene_assets[("Model assets<br/>content")]
end

subgraph group_vendor["Renderer vendor"]
  node_renderer_core["Sample Renderer<br/>gltf renderer"]
  node_materials_ext["Extensions<br/>gltf feature set"]
end

subgraph group_delivery["Build and publish"]
  node_rollup["Rollup<br/>bundler<br/>[rollup.config.js]"]
  node_dist[("dist<br/>static output")]
  node_github_pages["GitHub Pages<br/>hosting"]
end

node_index_html -->|"loads"| node_root_entry
node_root_entry -->|"starts"| node_app_bootstrap
node_app_bootstrap -->|"mounts"| node_ui_layer
node_app_bootstrap -->|"creates"| node_viewer_state
node_ui_layer -->|"events"| node_viewer_state
node_viewer_state -->|"resolves"| node_path_provider
node_url_inputs -->|"configures"| node_viewer_state
node_drop_inputs -->|"provides"| node_path_provider
node_path_provider -->|"locates"| node_scene_assets
node_viewer_state -->|"configures"| node_renderer_core
node_renderer_core -->|"renders on"| node_webgl_runtime
node_renderer_core -->|"supports"| node_materials_ext
node_scene_assets -->|"loads"| node_renderer_core
node_ui_layer -->|"styled by"| node_ui_styles
node_rollup -->|"builds"| node_dist
node_dist -->|"publishes"| node_github_pages
node_app_bootstrap -->|"wires"| node_renderer_core
node_viewer_state -->|"reflects"| node_ui_layer

click node_index_html "https://github.com/khronosgroup/gltf-sample-viewer/blob/main/index.html"
click node_root_entry "https://github.com/khronosgroup/gltf-sample-viewer/blob/main/main.js"
click node_app_bootstrap "https://github.com/khronosgroup/gltf-sample-viewer/blob/main/src/main.js"
click node_ui_layer "https://github.com/khronosgroup/gltf-sample-viewer/blob/main/src/ui/ui.js"
click node_ui_styles "https://github.com/khronosgroup/gltf-sample-viewer/blob/main/src/ui/sass.scss"
click node_viewer_state "https://github.com/khronosgroup/gltf-sample-viewer/blob/main/src/logic/uimodel.js"
click node_path_provider "https://github.com/khronosgroup/gltf-sample-viewer/blob/main/src/model_path_provider.js"
click node_renderer_core "https://github.com/khronosgroup/gltf-sample-viewer/tree/main/glTF-Sample-Renderer"
click node_materials_ext "https://github.com/khronosgroup/gltf-sample-viewer/tree/main/glTF-Sample-Renderer"
click node_rollup "https://github.com/khronosgroup/gltf-sample-viewer/blob/main/rollup.config.js"
click node_github_pages "https://github.com/khronosgroup/gltf-sample-viewer/blob/main/.github/workflows/Publish_to_Github_Pages.yml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_index_html,node_root_entry,node_app_bootstrap,node_ui_layer,node_ui_styles,node_viewer_state,node_path_provider,node_url_inputs,node_drop_inputs,node_webgl_runtime,node_scene_assets toneBlue
class node_renderer_core,node_materials_ext toneAmber
class node_rollup,node_dist,node_github_pages toneMint
```

## Components

### Viewer app

Browser-side viewer shell, UI, and state orchestration.

- [index.html](https://github.com/khronosgroup/gltf-sample-viewer/blob/main/index.html): shell page · Browser document that hosts the viewer. · `index.html`
- [main.js](https://github.com/khronosgroup/gltf-sample-viewer/blob/main/main.js): browser entry · Top-level entry that forwards into the application bundle. · `main.js`
- [App bootstrap](https://github.com/khronosgroup/gltf-sample-viewer/blob/main/src/main.js): startup · Initial application wiring and launch sequence. · `src/main.js`
- [UI controls](https://github.com/khronosgroup/gltf-sample-viewer/blob/main/src/ui/ui.js): presentation · Viewer control surface for loading, toggles, stats, and debug actions. · `src/ui/ui.js`
- [UI styles](https://github.com/khronosgroup/gltf-sample-viewer/blob/main/src/ui/sass.scss): sass · Presentation styling for the in-browser viewer. · `src/ui/sass.scss`
- [UI model](https://github.com/khronosgroup/gltf-sample-viewer/blob/main/src/logic/uimodel.js): state model · Central state and interaction boundary between controls and rendering. · `src/logic/uimodel.js`
- [Path provider](https://github.com/khronosgroup/gltf-sample-viewer/blob/main/src/model_path_provider.js): asset resolver · Resolves model and asset locations for local, remote, and dropped content. · `src/model_path_provider.js`
- **URL params**: input source · Query-driven viewer configuration and external content selection.
- **Drag and drop**: input source · Local file input path for loading glTF assets in the browser.
- **WebGL 2.0**: browser runtime · Client-side GPU runtime used to render the scene.
- **Model assets**: content · glTF, HDR, textures, and related scene resources consumed by the viewer.

### Renderer vendor

Vendored glTF rendering engine used by the viewer.

- [Sample Renderer](https://github.com/khronosgroup/gltf-sample-viewer/tree/main/glTF-Sample-Renderer): gltf renderer · Vendored glTF rendering engine for loading, shading, and animation. · `glTF-Sample-Renderer`
- [Extensions](https://github.com/khronosgroup/gltf-sample-viewer/tree/main/glTF-Sample-Renderer): gltf feature set · Compression, lighting, materials, variants, and other supported glTF extensions. · `glTF-Sample-Renderer`

### Build and publish

Frontend bundling and static hosting pipeline.

- [Rollup](https://github.com/khronosgroup/gltf-sample-viewer/blob/main/rollup.config.js): bundler · Build pipeline that packages the browser application. · `rollup.config.js`
- **dist**: static output · Generated static site artifacts produced by the build.
- [GitHub Pages](https://github.com/khronosgroup/gltf-sample-viewer/blob/main/.github/workflows/Publish_to_Github_Pages.yml): hosting · Static deployment target for the published viewer. · `.github/workflows/Publish_to_Github_Pages.yml`

## Connections

- index.html → main.js: loads · The shell page loads the browser entry point.
- main.js → App bootstrap: starts · The entry forwards into the application bootstrap.
- App bootstrap → UI controls: mounts · Bootstrap initializes the viewer controls.
- App bootstrap → UI model: creates · Bootstrap creates the central UI and interaction model.
- UI controls → UI model: events · Control interactions update viewer state.
- UI model → Path provider: resolves · State uses asset resolution to locate model and resource inputs.
- URL params → UI model: configures · Query parameters seed viewer configuration.
- Drag and drop → Path provider: provides · Dropped files are normalized into loadable asset locations.
- Path provider → Model assets: locates · The resolver points the viewer at model and scene resources.
- UI model → Sample Renderer: configures · Viewer state drives renderer settings and scene setup.
- Sample Renderer → WebGL 2.0: renders on · The renderer executes against the browser WebGL runtime.
- Sample Renderer → Extensions: supports · Core renderer capabilities include glTF extensions and material features.
- Model assets → Sample Renderer: loads · Scene resources are consumed by the renderer.
- UI controls → UI styles: styled by · The control surface is separated from its Sass styling.
- Rollup → dist: builds · Rollup emits the static browser bundle.
- dist → GitHub Pages: publishes · Built artifacts are deployed as a static site.
- App bootstrap → Sample Renderer: wires · Application startup connects the viewer to the vendored renderer.
- UI model → UI controls: reflects · State changes feed back into the UI.
