skillZs
★ LIVE SKILL TAGS ★
>>> LIVE SKILLS INDEX <<<
* OPEN SOURCE *
NO LOGIN, NO TRACKING
※ REAL INSTALL DATA ※
← back to all skills
mohitmishra786/low-level-dev-skills462 installs

wasm-emscripten

WebAssembly with Emscripten skill for C/C++ to WASM compilation. Use when compiling C/C++ to WebAssembly with emcc, configuring EXPORTED_FUNCTIONS, understanding the WASM memory model, using Asyncify for async C code, debugging .wasm with browser devtools or wasm-opt, or targeting WASI vs browser environments. Activates on queries about Emscripten, emcc, WebAssembly from C/C++, WASM memory model, Asyncify, EXPORTED_FUNCTIONS, WASI, or wasm-opt.

How do I install this agent skill?

npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill wasm-emscripten
view source ↗

Is this agent skill safe to install?

  • Gen Agent Trust Hubpass

    The skill provides comprehensive instructions for compiling C/C++ to WebAssembly using Emscripten. All external resources and command-line tools mentioned are standard, well-known components of the WebAssembly development ecosystem.

  • Socketpass

    No alerts

  • Snykpass

    Risk: LOW · No issues

  • Runlayerpass

    1/2 files flagged

What does this agent skill do?

WebAssembly with Emscripten

Purpose

Guide agents through compiling C/C++ to WebAssembly using Emscripten: emcc flag selection, function exports, memory model configuration, Asyncify for asynchronous C code, debugging WASM binaries, and targeting WASI vs browser.

Triggers

  • "How do I compile C to WebAssembly with Emscripten?"
  • "How do I export a C function to JavaScript?"
  • "How does WebAssembly memory work with Emscripten?"
  • "How do I debug a .wasm file?"
  • "How do I use Asyncify to make synchronous C code async?"
  • "What's the difference between WASI and Emscripten browser target?"

Workflow

1. Setup and first build

# Install Emscripten SDK
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh    # add emcc to PATH

# Verify
emcc --version

# Compile C to WASM (browser target)
emcc hello.c -o hello.html          # generates hello.html + hello.js + hello.wasm
emcc hello.c -o hello.js            # just JS + WASM (no HTML shell)

# Serve locally (WASM requires HTTP, not file://)
python3 -m http.server 8080
# Open: http://localhost:8080/hello.html

2. Exporting functions to JavaScript

// math.c
#include <emscripten.h>

// EMSCRIPTEN_KEEPALIVE prevents dead-code elimination
EMSCRIPTEN_KEEPALIVE
int add(int a, int b) {
    return a + b;
}

EMSCRIPTEN_KEEPALIVE
double sqrt_approx(double x) {
    return x * 0.5 + 1.0;
}
# Export specific functions
emcc math.c -o math.js \
  -s EXPORTED_FUNCTIONS='["_add","_sqrt_approx"]' \
  -s EXPORTED_RUNTIME_METHODS='["ccall","cwrap"]' \
  -s MODULARIZE=1 \
  -s EXPORT_NAME=MathModule

# The leading underscore is required for C functions
// Using exported functions in JS
const Module = await MathModule();

// Direct call
const result = Module._add(3, 4);

// Via ccall (type-safe)
const result2 = Module.ccall('add', 'number', ['number', 'number'], [3, 4]);

// Via cwrap (creates a callable JS function)
const add = Module.cwrap('add', 'number', ['number', 'number']);
console.log(add(3, 4));  // 7

3. Memory model

Emscripten provides a linear memory heap accessible from both C and JS:

# Configure initial and maximum heap
emcc prog.c -o prog.js \
  -s INITIAL_MEMORY=16MB \
  -s MAXIMUM_MEMORY=256MB \
  -s ALLOW_MEMORY_GROWTH=1    # allow dynamic growth

# Stack size (default 64KB)
emcc prog.c -o prog.js -s STACK_SIZE=1MB

# Shared memory (for SharedArrayBuffer / threads)
emcc prog.c -o prog.js -s SHARED_MEMORY=1 -s USE_PTHREADS=1
// Accessing C memory from JS
const ptr = Module._malloc(1024);     // allocate
Module.HEAPU8.set([1, 2, 3], ptr);   // write bytes
Module._free(ptr);                     // free

// Read a C string
const strPtr = Module.ccall('get_message', 'number', [], []);
const str = Module.UTF8ToString(strPtr);

// Write a string to C
const jsStr = "hello";
const cStr = Module.stringToNewUTF8(jsStr);  // malloc + copy
Module._process_string(cStr);
Module._free(cStr);

4. Asyncify — synchronous C in async environments

Asyncify lets synchronous C code suspend and resume for async operations (like fetch(), sleep, etc.):

// async.c
#include <emscripten.h>

// Synchronous sleep in C (blocks C, but yields to JS event loop)
EM_JS(void, do_fetch, (const char *url), {
    // Emscripten generates wrappers to suspend C while JS runs
    Asyncify.handleAsync(async () => {
        const resp = await fetch(UTF8ToString(url));
        const text = await resp.text();
        console.log(text);
    });
});

void process_url(const char *url) {
    do_fetch(url);     // looks synchronous in C
    printf("fetch complete\n");
}
# Enable Asyncify
emcc async.c -o async.js \
  -s ASYNCIFY \
  -s ASYNCIFY_STACK_SIZE=16384 \
  -O2   # Asyncify works better with optimization

5. Optimization and wasm-opt

# Optimization levels
emcc prog.c -O0 -o prog.js    # no optimization (fastest build)
emcc prog.c -O2 -o prog.js    # balanced
emcc prog.c -O3 -o prog.js    # aggressive
emcc prog.c -Os -o prog.js    # optimize for size
emcc prog.c -Oz -o prog.js    # aggressive size (Emscripten's smallest)

# Post-process with wasm-opt (Binaryen)
wasm-opt -Oz -o prog.opt.wasm prog.wasm    # optimize for size
wasm-opt -O4 -o prog.opt.wasm prog.wasm    # optimize for speed

# Compare sizes
ls -lh prog.wasm prog.opt.wasm

6. Debugging WASM

# Build with debug info
emcc prog.c -g -O0 -o prog.html \
  -s ASSERTIONS=1 \
  -s SAFE_HEAP=1      # catch misaligned accesses

# In Chrome DevTools:
# Sources → prog.wasm → line-by-line C source debugging
# (requires -g and browser with WASM debugging support)

# LLDB with WASM (wasmtime)
# See skills/runtimes/wasm-wasmtime for CLI WASM debugging
# Emscripten debug helpers
emcc prog.c -o prog.js \
  -s ASSERTIONS=2       # extensive runtime checks
  -s SAFE_HEAP=1        # sanitize heap accesses
  -s STACK_OVERFLOW_CHECK=1

# Print generated JS
emcc prog.c -o prog.js && cat prog.js | head -100

7. WASI vs browser target

FeatureBrowser (Emscripten)WASI
Host APIsWeb APIs (fetch, WebGL, etc.)POSIX subset (files, stdin/stdout)
RuntimeBrowser JS enginewasmtime, wasmer, WAMR, Node.js
ThreadsSharedArrayBuffer + pthreadswasi-threads (limited)
Networkingfetch(), WebSocketwasi-http (preview2)
Use caseWeb applicationsServer-side, CLI tools, edge
# Build for WASI (no browser JS, pure WASM)
emcc prog.c -o prog.wasm --target=wasi

# Or use wasi-sdk (better WASI support than Emscripten)
/opt/wasi-sdk/bin/clang --sysroot=/opt/wasi-sdk/share/wasi-sysroot \
  prog.c -o prog.wasm
wasmtime prog.wasm

For Emscripten linker flags reference, see references/emscripten-linker-flags.md.

Related skills

  • Use skills/runtimes/wasm-wasmtime for server-side WASM with wasmtime CLI and Rust embedding
  • Use skills/compilers/clang for Clang-based WASM compilation with WASI SDK
  • Use skills/binaries/elf-inspection for inspecting WASM binary structure

Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.

<a href="https://skillzs.dev/skills/mohitmishra786/low-level-dev-skills/wasm-emscripten">View wasm-emscripten on skillZs</a>