GitHub Pages deployment
npm run build creates dist/; no server-side code or upload endpoint exists. The production artifact contains the browser application, examples, documentation, root license, and an optional prebuilt Wasm module. Tests, benchmarks and native C++ sources are not copied into the web root.
Bundled examples
The Examples chooser reads examples/manifest.json, generated by the build from all supported structure files under examples/, including nested folders. Add a CFG, LAMMPS dump, XYZ/extXYZ or PDB file and rebuild; no HTML or JavaScript list needs to be edited. File headers identify supported data, so logs and unrelated files do not appear. Hidden files and symlinks are ignored.
Files with a shared filename pattern and distinct numeric indices become one sequence, ordered by index. Formats and folders stay separate; gaps are reported in the sequence description. A folder containing just one recognized sequence appears as a folder entry, including the bundled fixed_end_climb/ NEB example. The manifest records every sequence file rather than assuming a fixed frame count.
Optional descriptions live in examples/metadata.json, keyed by relative file or folder path (for example, "hea-fcc-screw.dump": "FCC high-entropy alloy with a screw dislocation"). For folders with several sources, a sequence key uses its filename pattern, such as "runs/replica.{number}.cfg". Unlisted examples receive format and size or sequence details automatically. Use {count} in a description to include the current number of source files. The metadata file does not create chooser entries.
npm run dev discovers examples on each manifest request, so adding a file needs only reopening the chooser. Production writes the manifest into both the versioned runtime tree and the unversioned examples directory; it is generated output and does not need to be committed.
Documentation website
The build renders checked-in Markdown into dist/docs/index.html, guide pages, and dist/docs/features/*.html. Each feature page explains its controls, numerical definition and implementation. The top-bar Documentation link and panel ? links point to this static website. The documentation follows the viewer theme and also has its own theme switch.
npm run dev renders the same documentation routes on demand from their Markdown sources. No generated documentation files need to be committed. Production uses plain HTML and CSS and needs no server rendering. All navigation and viewer links are relative, including under a repository subpath such as /AlloyView/docs/.
Open local offers a file picker and a read-only webkitdirectory folder picker. Individual files and multi-file selections load directly when they form one source. A folder selection returns a complete FileList with relative paths, which AlloyView presents in its file/sequence chooser. No selected file is uploaded.
GitHub Actions
.github/workflows/deploy-pages.yml deploys on every push to main and can also be run manually. The workflow:
- checks out the repository and selects Node.js 24;
- runs the test suite;
- creates
dist/withnpm run build; - uploads the Pages artifact;
- deploys it to the protected
github-pagesenvironment.
Both jobs use the explicit ubuntu-24.04 runner to avoid automatic operating system changes. The test step prints node --version, making the build runtime visible in the Actions log. setup-node selects Node.js 24 for shell commands; JavaScript actions have their own runtime declared in their action.yml. The workflow uses configure-pages@v6, upload-pages-artifact@v5 and deploy-pages@v5, which use Node.js 24 directly or through their upload action. Updating Node.js locally does not change these action versions. The deployed website runs JavaScript and WebAssembly in the browser, without a Node.js server.
In the repository on GitHub, select Settings → Pages → Build and deployment → Source → GitHub Actions. No branch containing generated files, personal access token, deployment secret, or custom base-path setting is required.
All runtime paths are relative, so a project site at https://<owner>.github.io/<repository>/ works without rewriting URLs. All bundled examples and sequences are fetched from the same Pages origin. User-selected files are read with the browser File API and are not uploaded.
The build computes a content hash and places the complete runtime tree under assets/<hash>/. The HTML references this tree, so JavaScript imports, Workers, examples, styles and logos all use one build version. A change to a Worker also changes the URL of its client. This prevents independently cached modules from mixing incompatible file-loading message formats after a deployment. The current loader also accepts the earlier single-file message format. Unversioned entrypoints remain available for an older cached HTML document during the transition; newly generated HTML always uses the versioned tree.
WebGPU on GitHub Pages
The Pages build contains the GPU Worker and the same GPU preparation and cache code used locally. Enable GPU acceleration is on by default. AlloyView initializes WebGPU in the background, prepares the current frame, then loads the whole sequence if it fits or keeps nearby frames. The initial hardware budget is 2 GiB including calculation workspace; memory is allocated as needed, and allocation exhaustion reduces the budget and window. All calculations and buffers belong to the visitor's browser and GPU. The benchmark command is a development tool and is not run by GitHub Pages or required from visitors. Refreshing the page creates a new GPU device and cache.
Pages HTTPS meets WebGPU's secure-context requirement. WebGPU itself does not require the COOP/COEP headers used by the local development server. Availability still depends on browser version, graphics acceleration, GPU/driver support and browser blocklists. See Chrome's WebGPU troubleshooting guide and the current GPUWeb implementation status, particularly for Linux GPU and display-system combinations.
npm run benchmark:gpu -- --hardware --preload starts Chrome with --enable-unsafe-webgpu and, on Linux, explicit Vulkan flags. These options are not properties of the deployed website: a page cannot set a visitor's browser launch flags. A successful benchmark therefore does not establish availability in that visitor's ordinary browser.
After deployment, leave GPU acceleration enabled and wait for the cache indicator (GPU preparing, then resident-frame counts). Run a supported analysis, such as coordination number, and confirm its timing reports webgpu. If the browser cannot provide a usable adapter, preparation reports GPU unavailable and calculation falls back to CPU; the timing tooltip includes the fallback reason. For Chrome, chrome://gpu shows the browser's WebGPU status. These checks use the actual deployed application and browser settings.
Other static hosts
Serve the contents of dist/ with correct MIME types, especially application/wasm when the optional native core has been built.
JavaScript module Workers and the checked-in PTM, Voro++ and DXA Wasm modules load from the same versioned runtime tree. Cross-origin isolation is optional: the ordinary analysis pool works with either shared coordinate snapshots or resident private copies. Isolated DXA can use its reusable threaded Wasm pool and cooperative cancellation; its nonisolated fallback cancels synchronous native calculations by terminating the dedicated Worker. Background module initialization retains reusable resources across source changes. npm run dev and npm run preview nevertheless send:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin
These headers allow analysis Workers to share coordinate snapshots and enable the existing Emscripten pthreads DXA build. Every embedded resource must satisfy COEP (same-origin or an appropriate CORP/CORS response). AlloyView intentionally has no CDN resources, which keeps that deployment tractable.
GitHub Pages does not allow custom response headers. That is compatible with the current Worker pool: it uses memory-budgeted resident private coordinate copies inside the user's browser when crossOriginIsolated is false. GitHub still only serves static files and never performs the calculation or receives the selected structure. Shared CPU snapshots and threaded DXA require a host that supplies the COOP and COEP headers above (or an isolation service worker whose tradeoffs have been validated). The current Pages workflow uses the nonisolated fallback; WebGPU preparation and analysis work independently of shared CPU memory.