DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 968,873 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for WebAssembly is easy β€” a hello world example
Dorin
Dorin

Posted on • Updated on • Originally published at fodor.org

WebAssembly is easy β€” a hello world example

Introduction

I like to think of WebAssembly as of Assembly. It gives you a few simple building blocks that you can arrange and combine to create almost anything. It’s a bit like playing with Legos.

As a new technology though, it has a few entry barriers which can put off someone who just wanted to try it out. The code that is usually referred to as the β€œglue” between WASM and JS is not pretty and requires you to have a more in-depth knowledge of WASM to be able to make sense of or put together.

But there are ways to make developing in WebAssembly easy and enjoyable. I am going to talk about them below.

Your first β€œHello World” in WASM

It has become a tradition already to first attempt to write a β€œHello World” application in a new language that you are trying out. Usually this will just print out these words to the standard output or in some other visual way.

In WASM, it is a bit different though. The β€œHello World” equivalent is often an addition function, which takes two integer arguments and returns their sum. There is a good reason why we are not attempting to print a string. Strings do not exist in WebAssembly as a type. We can have a string of bytes in memory which have a string encoded but any manipulation will have to be done on a byte level.
This is our addition function in WASM (text format):


(module
  (func (export "add") (param $n1 i32) (param $n2 i32) (result i32)
    get_local $n1
    get_local $n2
    i32.add
  )
)

Let’s break this down quickly and see what’s happening there line by line:

  1. We declare a new module. All of your WebAssembly code has to be contained in a module.
  2. Declaring a function which we export with the name add. This will allow us to call it from JS with add(). Then we say that it has two parameters of type 32bit Integer named $n1 and $n2. Lastly we say that our function is going to return another 32bit Integer.
  3. Put on stack $n1 from local memory.
  4. Put on stack $n2 from local memory.
  5. The built-in i32.add function will take the last two values from the stack, add them and return the sum.

That it pretty much it. The syntax is not C/JS-like but pretty easy to understand. Every element is a node and we can have nodes nested in other nodes, which act as parameters.

How to run it

Now that you have your very first WebAssembly application, you want a quick and easy way to test it. This is where people often stumble.

To be able to test this function you will have to load the WASM code into JavaScript and call it from there. Our goal is to be able to call our add() function with two arguments and read the output number.

The easiest way to do this, that I know of, is using inline-webassembly NPM package. And you would end up with a JS file like this:

const iw = require('inline-webassembly');

iw(`
  (module
    (func (export "add") (param $n1 i32) (param $n2 i32) (result i32)
      get_local $n1
      get_local $n2
      i32.add
    )
  )`
).then((wasmModule) => {
  const sum = wasmModule.add(44, 99);
  console.log(`Sum = ${sum}`); // 143
});

Conclusion

Now that you know how you can easily create and use WebAssembly code, there is nothing stopping you from refactoring performance critical parts of your code using WASM.

Happy assembling!

Video

Top comments (13)

Collapse
 
mdamaceno profile image
Marco Damaceno

Man, this article surprised me! I didn't know how easy WebAssembly is. I didn't even know about calling it inside a javascript code. The name "Assembly" scares me. Now, I intend to learn this language though.

Collapse
 
dorin profile image
Dorin Author

I'm glad this inspired you to learn more!

Collapse
 
rolandcsibrei profile image
Roland Csibrei

I used the inline technique to precalculate large datasets in my current project and the speed gain is very very mentionable.

Thanks for the article! Have a great day!

Collapse
 
dorin profile image
Dorin Author

that's fantastic!

Collapse
 
not_jffrydsr profile image
@nobody

Isn't it strange how WASM looks much like common LISP ? 😎

Collapse
 
devhammed profile image
Hammed Oyedele

I am about to say this πŸ˜‚πŸ˜‚πŸ˜‚

Collapse
 
seniru profile image
Seniru Pasan Indira

Same πŸ€”

Collapse
 
darthwalsh profile image
Carl Walsh

I'm guessing this works only server-side, but to actually use WASM you'd probably want this in a browser, right? Could I generate a binary using inline-webassembly and serve it from my express server?

Collapse
 
dorin profile image
Dorin Author

Good question! This will work both back-end with an Express server and front-end in a browser.
The way inline-webassembly works is that it generates and executes the binary on the fly, so this will not be a separate step.
Let me know if you have questions on how to do that.

Collapse
 
gabbersepp profile image
Josef Biehler

I developed many years with X86 ASM just for fun. I like the idea applying WASM code inline :-D
But I am not sure if my colleagues also support this :D

Collapse
 
dorin profile image
Dorin Author

I know what you mean :) I'm not using this at work either.

Collapse
 
otumianempire profile image
Otu Michael

Up and running.. Thanks

This post blew up on DEV in 2020:

js visualized

πŸš€βš™οΈ JavaScript Visualized: the JavaScript Engine

As JavaScript devs, we usually don't have to deal with compilers ourselves. However, it's definitely good to know the basics of the JavaScript engine and see how it handles our human-friendly JS code, and turns it into something machines understand! πŸ₯³

Happy coding!