Benchmarking wasm (zig) vs benchmark

I would really like to start building my native apps (written in C/Zig/Go) for the web, so that it's easier for users to test them. I still had many questions though.
  • How do I even build a zig app to wasm and then how do I load it in the browser?
  • How do I use opengl or access the filesystem?
  • How slower is running in the browser compared to native?
  • How slower is WebAssembly compared to JavaScript?
  • Compiling zig projects as .wasm files

    It looks like nearly every release of zig changes the build system, so the instructions I found on the internet were out of date. Here's my method that works with version 0.13.0. Put this in main.zig
    extern fn print(i64) void;
    
    export fn addprint(a: i32, b: i32) i32 {
    	print(a + b);
    	return a + b;
    }
    
    The "extern" function is something written in JS that we would like our zig program to access. Then compile with the following options:
    zig build-exe main.zig -target wasm32-freestanding -fno-entry -OReleaseFast --export=addprint
    
    This will a main.wasm file that is ready to be used from JS!
    --export=addprint is the name of the function we would later want to call from JS.
    -OReleaseFast makes the resulting binary way smaller. Running wasm2wat main.wasm on zig's output shows how much useless stuff the default debug build has.

    Loading .wasm in JS

    The basic process is to first download the code with fetch and then instantiate it.
    const imports = { env: { print: n => console.log("wasm:", n) } };
    const wasm = await WebAssembly.instantiateStreaming(fetch("main.wasm"), import)
    wasm.instance.exports.addprint(4, 5)
    
    This should print "wasm: 9" to the js console. You can test it both in a browser, but don't forget to start an http server first with python3 -m http.server. The process for loading in bun is similar:
    const imports = { env: { print: n => console.log("wasm:", n) } };
    const code = await Bun.file("main.wasm").arrayBuffer();
    const wasm = await WebAssembly.instantiate(code, imports);
    wasm.instance.exports.addprint(4, 5);
    

    Trivial computations