backgroundradial

@wasmer/sdk adds Node.js and Bun support

syrusakbary avatar
syrusakbary
Syrus Akbary

Founder & CEO

wasmer-js

October 31, 2024

arrowBack to articles
Post cover image

A few months ago we launched the revamped version of Wasmer SDK for Javascript. Unfortunately it had one major limitation: it could only run in the browser*.

Today we are incredibly excited to announce full support for Node.js/Bun in @wasmer/sdk, after one member of our community asked about it on Wasmer’s Discord a few weeks ago.

Thanks to this new advancement, now you can run Clang not only on the Browser but also inside Node.js (without having any other requirements installed… just vanilla Node.js), or even Python or any other package already available in wasmer.io.

Screenshot of Wasmer JS SDK running in Node.js

Source code available here: github.com/wasmerio/wasmer-js/blob/node/examples/node/example.mjs

Lets dig deeper on how we have made the Wasmer JS SDK available in Node and Bun.

*The reason for this limitation is that @wasmer/sdk requires Javascript Workers to support subprocesses and non-blocking stdin/stdout, but the Worker APIs are different on the browser and Node.js

What are Javascript Workers

Javascript is single threaded by default. In some cases, you may want to execute your code in another thread to prevent freezing your website screen, or to parallelize compute.

To fulfill those needs, Web Workers were introduced to the browser APIs a few years ago as a way to allow creating new background threads from Javascript (allowing the possibility to have a multi threaded app in the web).

Those threads communicate through messages/events:

// This initiates the worker
// Eg: creates a new thread and executes worker.js source on it
const myWorker = new Worker("worker.js");

myWorker.postMessage("message");
console.log("Message posted to worker");

Then, in the worker.js , you’ll have something like (in your browser)

global.onmessage = (e) => {
  console.log("Message received from main script");
  const workerResult = `Result: ${e.data}`;
};

Node.js threads

Node.js followed suit and added support for threads via workers with worker_threads.

When first implemented, it was believed that having exactly the same browser’s Web Worker API in Node.js would incur to some limitations, which is why Node.js decided to create a new Worker specification, that even though was close to the browser specification it was not fully compatible with it.

Deno has demonstrated that is fully possible to have exactly the Worker API working server-side without issues, but by the time it was demonstrated it was too late for Node.js to change their worker_threads.Worker spec again.

Node’s worker_threads.Worker API differs from the Browser’s Worker in three main ways (although there are many more subtle differences):

  • It doesn’t use DOM-style events (Event.dataEvent.type, etc) as the browser does
  • It doesn’t support receiving module URL, Blob URL or Data URL (Node.js one only accepts file locations as workers)
  • It lacks support for the WorkerGlobalScope, present in Worker threads in the browser

Getting things to work

After a bit of research we found the NPM package web-worker that helped closing that gap between Browser and Node Worker APIs.

We started using it with some success, which lead us to discover another issue: Node.js apps didn’t close automatically after using the @wasmer/sdk.

After a bit of research, we realized that the main Node process was not exiting because the Workers created with it were not being closed automatically after the execution of a program.

Once we got everything properly shutting down when programs were exiting… @wasmer/sdk was properly working and ready to be used by the public!

So we tested things, made sure everything worked smoothly and released the SDK v0.9.0.

https://www.npmjs.com/package/@wasmer/sdk

One last thing…

You can now use any Wasmer package in your Node.js application without an issue.

We have set up an example for using cowsay in Node/Bun that will help to test things locally: github.com/wasmerio/wasmer-js/blob/main/examples/node/example.mjs

Lets see from a real world example how Bitte Protocol has been using the @wasmer/sdk in Node to power their AI agents.

The source code of their example is available on Github: github.com/BitteProtocol/bitte-wasmer-agent. You can also check their announcement in X (formerly Twitter).


Stay Updated

Thanks for being part of the Wasmer journey!

About the Author

Syrus Akbary is an enterpreneur and programmer. Specifically known for his contributions to the field of WebAssembly. He is the Founder and CEO of Wasmer, an innovative company that focuses on creating developer tools and infrastructure for running Wasm

Syrus Akbary avatar
Syrus Akbary
Syrus Akbary

Founder & CEO

Read more
Post cover image

wasmer runtimejavascriptwasmer-jsbrowser

Introducing the new Wasmer JS SDK

Michael BryanDecember 13, 2023