Description: This is a template repository for testing out WebGPU and WASM
Link to website: https://bellescoincidences.github.io/webgpu-wasm-template/ Repository: https://github.com/bellescoincidences/webgpu-wasm-template
webgpu-wasm-template/
├── .gitignore
├── README.md
├── index.html # The main markup file requiring a canvas for the WebGPU context
├── package.json # Build configuration: this file sets up Vite and provides the compilation scripts for Emscripten. Vite provides a fast, modern build pipeline for TypeScript, whilst Emscripten handles the C++ to WASM compilation
├── src/
│ └── main.ts # WebGPU orchestration: This script loads the WASM module, executes the C++ function, and then initialises a basic WebGPU render pass. Importing the ES6 module generated by Emscripten allows seamless WASM instantiation
└── wasm/
└── compute.cpp # A simple C++ file to demonstrate mathematical operations offloaded to WebAssembly. EMSCRIPTEN_KEEPALIVE prevents the compiler from discarding this function during optimisation- To test this codebase, ensure
Node.jsand theEmscripten SDKare installed locally. - Running
npm installfollowed bynpm run dev(after executing thebuild:wasmscript) will compile the application and launch the development server. - Please also ensure that
Homebrewis installed, and that you have downloaded>=Python 3.10into your brew inventory binaryenEnsureBinaryenis installed. AlthoughHomebrewusually fetches this automatically, it might be missing or unlinked. This package provides thewasm-optbinary explicitly requested in the error trace:brew install binaryenllvmRunbrew install llvmand add to yourPATH:echo 'export PATH="/opt/homebrew/opt/llvm/bin:$PATH"' >> /Users/victoriamckinney/.zshrc- Homebrew recently separated the LLVM linker into an independent package. It must be installed alongside the main compiler:
brew install lld. This package provides thewasm-ldbinary, which is explicitly required to stitch the compiled object files into a finishedWebAssemblymodule.
- Homebrew recently separated the LLVM linker into an independent package. It must be installed alongside the main compiler:
Before starting, please ensure python in brew inventory is added to path:
echo 'export PATH="$(brew --prefix python@3.12)/libexec/bin:$PATH"' >> ~/.zshrc # python 3.12 is most stable for this
source ~/.zshrc # to refresh environment
python --version # verify python envSetting up a macOS environment for WebAssembly development via Homebrew is straightforward. Here are the precise terminal commands required to verify existing software and install missing packages.
Node.js provides the runtime environment, and npm manages packages like Vite and TypeScript.
To check for an existing installation: Execute the following commands in the macOS terminal.
node -v
npm -vIf version numbers (e.g., v20.11.0) are printed to the console, the tools are already installed and ready for use.
To install via Homebrew: If the terminal returns a command not found error, proceed with the installation.
brew install nodeHomebrew automatically downloads and symlinks the latest stable versions of both node.js and npm into the system path.
Emscripten is the toolchain required to compile C++ (.cpp) files into WebAssembly (.wasm) and JavaScript bridge files.
To check for an existing installation:
Verify the presence of the Emscripten Compiler Frontend (emcc).
emcc -vA successful response will output the Emscripten version and the underlying Clang compiler details.
If you get an error when running emcc -v try the following steps:
To install via Homebrew: If the compiler is not found, install it using the following command.
brew install emscriptenWhile the official emsdk repository is heavily utilised in enterprise CI/CD pipelines, the Homebrewformula is exceptionally convenient for local macOS development and perfectly serves the WebGPU template architecture previously discussed.
npm run build:wasm
npm run devNode.jsis a free, open-source, cross-platformJavaScriptruntime environment that lets developers:- create servers
- web apps
- command line tools
- scripts
Viteis a build tool that aims to provide a faster and leaner development experience for modern web projects. It consists of two major parts:- A dev server that provides rich feature enhancements over native ES modules, for example extremely fast Hot Module Replacement (HMR).
- A build command that bundles your code with Rolldown, pre-configured to output highly optimised static assets for production.
- [
Emscripten] is a complete Open Source compiler toolchain toWebAssembly. Using Emscripten you can:- Compile
CandC++code (or any other language that usesLLVMintoWebAssembly), and run it on theWeb,Node. js, or otherWasmruntimes.
- Compile
Web Assembly (WASM)WebAssembly(WASM) is a highly-efficient binary format that allows code written in languages such as C++ or Rust to run directly within a web browser at near-native speeds.- It operates alongside standard web technologies to process demanding tasks, offering raw computational power for complex applications without relying solely on
JavaScript.
WebGPUWebGPUis a modern technology that allows web browsers to communicate directly with a device's graphics card to perform complex calculations and render high-quality images.- It provides a highly efficient, low-level connection to the hardware, unlocking native-like graphical performance for applications directly on the internet.
-
emccerror when runningnpm run build:wasmwebgpu-wasm-template % npm run build:wasm > webgpu-wasm-template@1.0.0 build:wasm > emcc wasm/compute.cpp -o public/compute.js -s EXPORTED_RUNTIME_METHODS='["ccall"]' -s MODULARIZE=1 -s EXPORT_ES6=1 emcc: warning: config file not found: /opt/homebrew/Cellar/emscripten/5.0.5/libexec/.emscripten. You can create one by hand or run `emcc --generate-config` emcc: error: BINARYEN_ROOT not set in config (/opt/homebrew/Cellar/emscripten/5.0.5/libexec/.emscripten), and `wasm-opt` not found in PATH webgpu-wasm-template % emcc -v emcc: warning: config file not found: /opt/homebrew/Cellar/emscripten/5.0.5/libexec/.emscripten. You can create one by hand or run `emcc --generate-config` emcc: error: BINARYEN_ROOT not set in config (/opt/homebrew/Cellar/emscripten/5.0.5/libexec/.emscripten), and `wasm-opt` not found in PATH
Solution
emcc --generate-config
This instructs
Emscriptento build the missing.emscriptenfile and auto-detect localHomebrewpaths.
-
llvmerror when runningnpm run build:wasm> webgpu-wasm-template % npm run build:wasm > webgpu-wasm-template@1.0.0 build:wasm > emcc wasm/compute.cpp -o public/compute.js -s EXPORTED_RUNTIME_METHODS='["ccall"]' -s MODULARIZE=1 -s EXPORT_ES6=1 emcc: warning: LLVM version for clang executable "/usr/bin/clang" appears incorrect (seeing "21.0", expected "23") [-Wversion-check] shared:CRITICAL: LLVM has not been built with the WebAssembly backend, clang reports: =========================================================================== aarch64 - AArch64 (little endian) aarch64_32 - AArch64 (little endian ILP32) aarch64_be - AArch64 (big endian) arm - ARM arm64 - ARM64 (little endian) arm64_32 - ARM64 (little endian ILP32) armeb - ARM (big endian) thumb - Thumb thumbeb - Thumb (big endian) x86 - 32-bit X86: Pentium-Pro and above x86-64 - 64-bit X86: EM64T and AMD64 =========================================================================== shared:INFO: (Emscripten: Running sanity checks)
Fix
- The
Emscriptenconfiguration auto-generator fell into a trap.Homebrewinstalls itsLLVMpackage as 'keg-only', meaning it is deliberately hidden from the main system path to prevent conflicts with Apple's nativeXcodetools.
- Because it was hidden, the configuration script grabbed the first compiler available—Apple's default system
Clang(ie./usr/bin/clang).
- As this error points out, Apple's
Clangdoes not supportWebAssemblycompilation. To resolve this, theHomebrew LLVMmust be temporarily exposed to the terminal path, the bad configuration moved, and a new one generated.
Run these commands to get going again. Forcing the WebAssembly-compatible LLVM into the path ensures Emscripten maps the correct compiler dependencies during the setup phase:
# 1. Prioritise the Homebrew LLVM in the current terminal session export PATH="$(brew --prefix llvm)/bin:$PATH" # 2. Rename the incorrect configuration file instead of deleting it mv "$(brew --prefix emscripten)/libexec/.emscripten" "$(brew --prefix emscripten)/libexec/.emscripten.backup" # 3. Generate a fresh, correct configuration emcc --generate-config # 4. Execute the compilation script once more npm run build:wasm
Output should look like this:
MacBook Air webgpu-wasm-template % emcc --generate-config An Emscripten settings file has been generated at: /opt/homebrew/Cellar/emscripten/5.0.5/libexec/.emscripten It contains our best guesses for the important paths, which are: LLVM_ROOT = /usr/bin BINARYEN_ROOT = /opt/homebrew NODE_JS = /opt/homebrew/bin/node Please edit the file if any of those are incorrect.
- The