Skip to content
Latchkey

CI/CD for an Emscripten WASM App with GitHub Actions

Compile C/C++ to WASM and ship the web bundle on every push.

Emscripten compiles C/C++ to WebAssembly plus a JavaScript glue layer that the web app loads. This recipe sets up the Emscripten SDK, builds the WASM module, bundles the host, and deploys the static output.

What the pipeline does

  • set up the Emscripten SDK with emsdk
  • compile to WASM with emcc or make
  • bundle the JS host with Vite
  • run the JS test suite
  • deploy the dist directory

The workflow

mymindstorm/setup-emsdk installs and caches the toolchain; emcc emits the .wasm and .js glue, which Vite then bundles into the web app.

.github/workflows/ci.yml
name: CI
on:
  push:
    branches: [main]
  pull_request:
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: mymindstorm/setup-emsdk@v14
        with:
          version: latest
          actions-cache-folder: emsdk-cache
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: emcc src/core.c -O3 -o public/core.js -s MODULARIZE=1
      - run: npm ci
      - run: npx vitest run
      - run: npm run build
      - uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist

Caching and speed

setup-emsdk caches the toolchain via actions-cache-folder, and cache: npm covers the JS install. The emcc compile is the slow step; cheaper managed runners such as Latchkey (around 69% cheaper than GitHub-hosted) keep builds affordable and auto-retry transient SDK download failures.

Deploying

Deploy dist to Pages, Netlify, or S3+CloudFront, and serve the .wasm with the application/wasm MIME type so streaming compilation works. Enable cross-origin isolation headers if the module uses threads (SharedArrayBuffer).

Key takeaways

  • setup-emsdk installs and caches the Emscripten toolchain.
  • Serve .wasm with the application/wasm MIME type for streaming.
  • Threaded WASM needs cross-origin isolation headers.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →