Learning WebAssembly #1: Hello, World of Wasm!

Getting started with WebAssembly: writing and executing a simple program in Wat.


This is the first part of a series about programming in WebAssembly (Wasm) for beginners. The goal is to give you the first impression of what Wasm is and how it can be beneficial for your own projects. The further the series goes the deeper we will delve into the topic.

I suppose you have already heard about WebAssembly; how performant, lightweight, secure, and overall promising it is. Otherwise, you probably would not be reading this text right now, would you? So, I will just skip all that fluff and go directly to the more interesting stuff: like how to write Wasm code and how to actually use it.

Wasm and Wat

Wasm is a binary format (files with the .wasm extension). It also has a textual representation called Wat (files with the .wat extension). Wat could easily be generated from the binary format, for example via developer tools in the browser.

Albeit Wat is a text format readable by humans, it is still pretty low-level — programming complex systems in Wat would quickly become a nightmare. But no worries, Wasm can be compiled from many languages like Rust, C/C++, Go, or Kotlin. Just choose your favourite one!

Hello, WebAssembly!

To understand the very basics we will start at quite a low-level. Well, not on the binary level, all in all, it was never meant to be written or read by humans. We will create a simple Hello world program in Wat, the WebAssembly text format.

Copy and save the following code into a file (hello.wat):

(module
  (func (export "main")
        (result i32)
    i32.const 42
    return))

Wait a minute, there is no “Hello” in the code above! This is the first catch: WebAssembly does not have a value type that would represent strings. We have only numeric types in our base equipment. For now, 42, the answer to the ultimate question of life, the universe, and everything, will serve as our “hello, world” phrase.

To test the code, we can use the WebAssembly Binary Toolkit. First, we must compile the Wat text format into the Wasm binary format (hello.wasm):

$ wat2wasm hello.wat -o hello.wasm

We can run it with an interpreter from the same toolkit:

$ wasm-interp --run-all-exports hello.wasm

The following output should appear:

main() => i32:42

We can run the same code in the browser, too:

<html>
<body>
<script>
  WebAssembly
    .instantiateStreaming(fetch('hello.wasm'))
    .then(({instance}) =>
        console.log(instance.exports.main())
    );
</script>
</body>
</html>

For the Fetch API to work the HTML page must be served via HTTP(s). Tools like dir2http do the job.

After opening the page in a browser we should see the answer in the dev console:

» 42

As just shown, the identical WebAssembly program can run both inside and outside a browser. This shows the great potential of WebAssembly to become a universal programming platform for both web clients and server applications.

Further Steps

All right, we have written our first program in Wasm and now we know the answer to the ultimate question. What's next?

In the second part of this series, we will go deeper and explain byte by byte what actually happens under the hood.

Stay tuned!