# Zig WebAssembly

**URL:** <https://ziggit.dev/t/zig-webassembly/2550>\
**Category:** Help\
**Tags:** wasm\
**Created:** [December 22, 2023, 5:27pm UTC](https://ziggit.dev/t/zig-webassembly/2550 "2023-12-22T17:27:19Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![FeliceMente](https://ziggit.dev/user_avatar/ziggit.dev/felicemente/32/1403_2.png) [@FeliceMente](https://ziggit.dev/u/FeliceMente)\
**Post date:** [December 22, 2023, 5:27pm UTC](https://ziggit.dev/t/zig-webassembly/2550/1 "2023-12-22T17:27:19Z")

</div>

I’m trying to create a basic math library in Webassembly using Zig, and use it in Node.js, following this tutorial:

[![](https://ziggit.dev/uploads/default/original/2X/b/b64ec24644a5ff94b1f88f936ee3b6d7af3535fe.jpeg "Programming WebAssembly with Zig - Getting Started with the ZIG programming language") ](https://www.youtube.com/watch?v=R2GW197izwQ)

I created this math.zig file:

```zig
export fn add(n1: i32, n2: i32) i32 {
    return n1 + n2;
}

```

and created the wasm library with:  
zig build-lib math.zig -target wasm32-freestanding -dynamic

I then created this node.js file (index.js):

```js
const fs = require("fs");

const wasmBuffer = fs.readFileSync("./math.wasm");

WebAssembly.instantiate(wasmBuffer).then((wasmModule) => {
    console.log(wasmModule.instance.exports.add(1, 2));
});

```

and ran it with “node index.js”, but always get the error:  
`TypeError: wasmModule.instance.exports.add is not a function`

I’m pretty sure I’m king some mistake generating the WASM library from Zig. It seems the add function doesn’t get exported.

---

<div class="post-metadata">

**Author:** ![permutationlock](https://ziggit.dev/user_avatar/ziggit.dev/permutationlock/32/9958_2.png) [@permutationlock](https://ziggit.dev/u/permutationlock)\
**Post date:** [December 22, 2023, 5:38pm UTC](https://ziggit.dev/t/zig-webassembly/2550/2 "2023-12-22T17:38:54Z")

</div>

I believe that there was a [recent change](https://github.com/ziglang/zig/pull/17815) to now use `build-exe` with `-fno-entry` for `wasm` targets, not `build-lib` with `-dynamic`.

---

<div class="post-metadata">

**Author:** ![castholm](https://ziggit.dev/user_avatar/ziggit.dev/castholm/32/1330_2.png) [@castholm](https://ziggit.dev/u/castholm)\
**Post date:** [December 22, 2023, 6:39pm UTC](https://ziggit.dev/t/zig-webassembly/2550/3 "2023-12-22T18:39:45Z")

</div>

> [@permutationlock](#):
>
> I believe that there was a [recent change](https://github.com/ziglang/zig/pull/17815) to now use `build-exe` with `-fno-entry` for `wasm` targets, not `build-lib` with `-dynamic`.

In addition to this, you need to explicitly state which `export`ed functions/variables you want to include in the Wasm output, either by passing `-rdynamic` to include everything, or by repeatedly passing the `--entry=<symbol>` for each symbol you want to include.

So the complete invocation is

```sh
zig build-exe ./math.zig -target wasm32-freestanding -fno-entry -rdynamic

```

---

<div class="post-metadata">

**Author:** ![FeliceMente](https://ziggit.dev/user_avatar/ziggit.dev/felicemente/32/1403_2.png) [@FeliceMente](https://ziggit.dev/u/FeliceMente)\
**Post date:** [December 22, 2023, 10:17pm UTC](https://ziggit.dev/t/zig-webassembly/2550/4 "2023-12-22T22:17:17Z")

</div>

with Zig 0.11.0 I get “error: unrecognized parameter: ‘-fno-entry’”

---

<div class="post-metadata">

**Author:** ![castholm](https://ziggit.dev/user_avatar/ziggit.dev/castholm/32/1330_2.png) [@castholm](https://ziggit.dev/u/castholm)\
**Post date:** [December 22, 2023, 10:32pm UTC](https://ziggit.dev/t/zig-webassembly/2550/5 "2023-12-22T22:32:53Z")

</div>

Sorry, `-fno-entry` was only recently added to the 0.12.0-dev master branch of Zig. I would personally recommend you to download and use the master version of Zig since Zig is a fast-evolving language and ecosystem and information gets outdated very quickly, but if you want to stick with 0.11.0 I believe

```sh
zig build-lib ./math-zig target wasm32-freestanding -dynamic -rdynamic

```

should work.

---

<div class="post-metadata">

**Author:** ![FeliceMente](https://ziggit.dev/user_avatar/ziggit.dev/felicemente/32/1403_2.png) [@FeliceMente](https://ziggit.dev/u/FeliceMente)\
**Post date:** [December 22, 2023, 10:37pm UTC](https://ziggit.dev/t/zig-webassembly/2550/6 "2023-12-22T22:37:28Z")

</div>

> [@castholm](#):
>
> `zig build-lib ./math-zig target wasm32-freestanding -dynamic -rdynamic`

It worked, thanks. So I’d better study Zig with master branch instead 0f 0.11.0?

---

<div class="post-metadata">

**Author:** ![castholm](https://ziggit.dev/user_avatar/ziggit.dev/castholm/32/1330_2.png) [@castholm](https://ziggit.dev/u/castholm)\
**Post date:** [December 22, 2023, 10:52pm UTC](https://ziggit.dev/t/zig-webassembly/2550/7 "2023-12-22T22:52:06Z")

</div>

[The official “getting started” docs encourages using the master branch](https://ziglang.org/learn/getting-started/#tagged-release-or-nightly-build) and beginner resources like [ziglearn.org](https://ziglearn.org/#installation) or [Ziglings](https://codeberg.org/ziglings/exercises/#getting-started) also seem to agree. When asking for help and advice people will generally assume you’re on the latest master unless you explicitly state a different version.

---

<div class="post-metadata">

**Author:** ![dude\_the\_builder](https://ziggit.dev/user_avatar/ziggit.dev/dude_the_builder/32/557_2.png) [@dude\_the\_builder](https://ziggit.dev/u/dude_the_builder)\
**Post date:** [December 22, 2023, 11:03pm UTC](https://ziggit.dev/t/zig-webassembly/2550/8 "2023-12-22T23:03:16Z")

</div>

On a project I did a while back using 0.11, I had this in my `build.zig` and just tested it and produces a wasm module in `zig-out/lib` by running `zig build`:

```zig
    const lib = b.addSharedLibrary(.{
        .name = "mywasm",
        .root_source_file = .{ .path = "src/main.zig" },
        .target = .{
            .cpu_arch = .wasm32,
            .os_tag = .freestanding,
        },
        .optimize = .ReleaseSmall,
    });
    lib.export_symbol_names = &.{ "alloc", "free", "add", "sub", "zlog" };
    b.installArtifact(lib);

```

I think the `lib.export_symbol_names` is the key here.

---

<div class="post-metadata">

**Author:** ![chung-leong](https://ziggit.dev/user_avatar/ziggit.dev/chung-leong/32/999_2.png) [@chung-leong](https://ziggit.dev/u/chung-leong)\
**Post date:** [December 23, 2023, 2:06am UTC](https://ziggit.dev/t/zig-webassembly/2550/9 "2023-12-23T02:06:41Z")

</div>

Pardon the self-advertisement, but check out my project if you want to use Zig in JavaScript projects: [Zigar](https://github.com/chung-leong/zigar?tab=readme-ov-file#zigar).

It’s designed to make the process as seamless as possible. Just set up the rollup plugin and it’ll generate the WASM file for you. For Node you also have to option to run Zig code as native code (doen’t work in Node 20+ currently).

At the Pb2Zig project page you’ll find some nifty demos showing what can be done using Zig + WebAssembly.
