Skip to content

Repository files navigation

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


Repository Structure

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

Requirements

  • To test this codebase, ensure Node.js and the Emscripten SDK are installed locally.
  • Running npm install followed by npm run dev (after executing the build:wasm script) will compile the application and launch the development server.
  • Please also ensure that Homebrew is installed, and that you have downloaded >=Python 3.10 into your brew inventory
  • binaryen Ensure Binaryen is installed. Although Homebrew usually fetches this automatically, it might be missing or unlinked. This package provides the wasm-opt binary explicitly requested in the error trace: brew install binaryen
  • llvm Run brew install llvm and add to your PATH: 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 the wasm-ld binary, which is explicitly required to stitch the compiled object files into a finished WebAssembly module.

MacOS installation

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 env

Setting 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.

1. Node.js and npm

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 -v

If 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 node

Homebrew automatically downloads and symlinks the latest stable versions of both node.js and npm into the system path.

2. Emscripten

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 -v

A 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 emscripten

While 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.

2. Build

npm run build:wasm
npm run dev

Definitions

  • Node.js is a free, open-source, cross-platform JavaScript runtime environment that lets developers:
    • create servers
    • web apps
    • command line tools
    • scripts

source code

  • Vite is 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.

source code

  • [Emscripten] is a complete Open Source compiler toolchain to WebAssembly. Using Emscripten you can:
    • Compile C and C++ code (or any other language that uses LLVM into WebAssembly), and run it on the Web, Node. js, or other Wasm runtimes.

source code

  • 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.

source code

  • WebGPU
    • WebGPU is 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.

source code


Troubleshooting

  • emcc error 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: 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 Emscripten to build the missing .emscripten file and auto-detect local Homebrew paths.

  • llvm error when running npm 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 Emscripten configuration auto-generator fell into a trap. Homebrew installs its LLVM package as 'keg-only', meaning it is deliberately hidden from the main system path to prevent conflicts with Apple's native Xcode tools.
    • 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 Clang does not support WebAssembly compilation. To resolve this, the Homebrew LLVM must 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.

About

WebGPU and WASM template architecture

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages