• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar
  • Skip to footer
Codemotion Magazine

Codemotion Magazine

We code the future. Together

  • Magazine
  • Dev Hub
    • Community Manager
    • CTO
    • DevOps Engineer
    • Backend Developer
    • Frontend Developer
    • Web Developer
    • Mobile Developer
    • Game Developer
    • Machine Learning Developer
    • Blockchain Developer
    • Designer – CXO
    • Big Data Analyst
    • Security Manager
    • Cloud Manager
  • Articles
    • Stories
    • Events
  • Sign In
Home » Dev Hub » Web Developer » Getting started with WebAssembly and Rust
Web Developer

Getting started with WebAssembly and Rust

WebAssembly (or Wasm) is a portable binary code format designed to run on an isolated virtual stack machine. Not a replacement for JavaScript, but nonetheless a useful tool

Last update February 21, 2020 by Sergio Monteleone

Table Of Contents
  • So why WebAssembly?
  • … and why Rust?
  • Getting started: setup
  • Our first WebAssembly module
  • Calling WebAssembly from a web page
  • Conclusions

We live in a world where JavaScript code is run absolutely everywhere. We have it in browsers and in the backend with Node.js,  in desktop apps (Electron) and even on MCUs (low.js anyone?).

JavaScript has delivered to some extent on the promise – “write once, run anywhere” – that many have tried (and failed) to deliver in the past. Unfortunately the situation remains far from ideal, primarily because JavaScript was not designed with this goal in mind.

Several revisions of the ECMAScript standard have been released to improve the language and address its limitations. Furthermore, new and more expressive languages (yes TypeScript, we hear you) have been released to add missing features while maintaining complete compatibility with existing runtime engines. All of this has led to the fragmented ecosystem we all have to struggle with everyday, making the development of large projects very challenging.

On top of that, JavaScript is slow. Even with heavily optimized runtimes JavaScript code is always slower than native code (yes, V8, I’m talking about you and your speculative optimization). If this comes as a surprise to you, I suggest you download the ECMAScript specification and count how many steps are required to perform just an OrdinaryGetOwnProperty!

Therefore, when in need of native performance, developers have had to turn to native code (plug-ins, NPAPI, etc.), often with disastrous consequences in terms of security.

So why WebAssembly?

This is where WebAssembly comes to the rescue.

If you have never heard about WebAssembly, check out the talk Diwanshi Pandey, software engineer at Red Hat, gave at Codemotion Milan 2019!

WebAssembly, or Wasm for brevity, is essentially a portable binary code format designed to run on an isolated virtual stack machine. It is not a replacement for JavaScript but a companion tool that offers better performance where needed.

WebAssembly is a compilation target for C, C++, Go, and Rust among others. Developers can code in any of those languages and then compile their source into Wasm binaries. These then run alongside JS code in their applications.

There are many obvious reasons why WebAssembly is faster than JavaScript. First of all, binary Wasm is smaller and easier to parse than JS code – even when minified. More importantly, Wasm is a compilation target for statically typed languages. That means that there is less overhead when accessing variables or evaluating expressions (there is no  OrdinaryGetOwnProperty madness).

However, none of these is the factor that makes WebAssembly so special. After all, on a purely technical level, binary Wasm is not very different from Java’s bytecode or .NET Common Intermediate Language. But WebAssembly is an open standard and is already implemented in all the major browsers. Consequently, you don’t need a native plug-in to run Wasm code in your browser, no matter what platform, OS, or device you are using – that’s pretty unique.

… and why Rust?

There are many things to consider when choosing the technologies and languages to use for a project. To use WebAssembly we must use a language which can be compiled into Wasm. Transitioning from JavaScript to C or C++ can be challenging to say the least.

Go would be a better alternative in this case, as it is concise and easy to read. However, there is always a trade-off between performance and readability. Go’s runtime offers a lot of features, but these come at the cost of the binary size:  the smallest Wasm file compiled from Go is around 2 MB, while 10 MB is typical. That is huge compared to files compiled from C++ and Rust, which are typically just a few KB.

Rust is just as powerful as C++ when it comes to performance, but is safer, especially when dealing with memory management. Moreover, Rust’s support for WebAssembly is mature and complete, offering tools and bindings to integrate it into existing JavaScript projects.

Getting started: setup

To begin working with Rust and WebAssembly, one must obviously have the Rust toolchain installed. The best (and recommended) way to manage the Rust toolchain is via the rustup tool.

Installing rustup is as easy as launching a Bash script (the rustup-init.sh script, in fact) with this one-line command:

# curl https://sh.rustup.rs -sSf | sh

If you are running Windows, luckily we live in the era of Nadella, and thus have plenty of options to get Bash up and running: the Windows Subsystem for Linux, Git for Windows’ own Bash, or Cygwin, just to name a few. If you don’t want to use Bash at all, there is an .exe version of rustup-init as well as standalone installers available for download from the Rust language project website.

The script will download and compile all the required tools including rustc (the Rust compiler) and cargo (Rust’s package manager).

The toolchain will be installed by default in $HOME/.cargo so be sure to add the $HOME/.cargo/bin to your PATH environment variable, or simply run the command

# source $HOME/.cargo/env

when opening a new shell.

Once the Rust toolchain is installed, we can proceed with installing Wasm-pack. Wasm-pack is an all in one tool to build, test and publish Rust-generated Wasm modules. To install it, simply type this command in your Bash prompt:

# curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh

Alternatively, you can again download the .exe file from the official website if you are on Windows.
Another useful tool to install is cargo-generate, which allows the creation of new projects based on existing templates. Since the Rust toolchain is already installed, we can use Cargo itself to download, compile and install cargo-generate, with this command:

# cargo install cargo-generate

If you do not already have them installed, we recommend installing git, node and npm – these may come in handy pretty soon.

Our first WebAssembly module

Let’s dive in and build our first Hello World project in Rust/WebAssembly: a web page that shows an alert!

First of all, we will create a new project using cargo generate, using a git repository as a template:

# cargo generate --git https://github.com/rustwasm/wasm-pack-template

When prompted for the project’s name, just type ‘hello’. The script will create the directory ‘hello’ and populate it with the files shipped with the template:

  • Cargo.toml – specifies dependencies and metadata for cargo (a sort of Rust equivalent of package.json);
  • src/lib.rs – contains the code of our Wasm module;
  • src/utils.rs – provides common utilities to debug Wasm code;

Let’s have a look at the lib.rs code in detail:

We import the utils module, and then proceed using the wasm_bindgen, to provide interoperation between our Rust and JavaScript codes.

In this simple example, wasm_bindgen is used to import the browser’s alert() function, so our Rust code can call it and display the “Hello, hello!” message (the string created by cargo generate is “Hello, <project_name>!” and our project is named “hello”). Feel free to change this message according to your preferences.

At the same time we export the greet() function, so that the JavaScript code using our Wasm module can call it.

When targeting Wasm, the wee_alloc allocator is the preferred choice, as it was explicitly designed for smaller code size, although it can be a bit slower than other allocators.

Now that our code is ready, we can proceed with building the project. To do that we will use the wasm-pack utility, which performs some sanity checks (ensuring we have the correct Rust version), compiles our code to Wasm, downloads and compiles all dependencies, and finally invokes wasm-bindgen to generate the JavaScript API bindings. All that with just one command:

# wasm-pack build

Once finished, the compiled artifacts are available in the pkg/ directory. This directory should contain these files:

  • hello_bg.wasm – our WebAssembly binary, which exports the greet() function;
  • hello.js – JavaScript glue that implements the interoperation layer between JS and Wasm;
  • hello.d.ts – TypeScript declarations for the JavaScript glue;
  • package.json – the metadata about this generated WebAssembly package;

Calling WebAssembly from a web page

The Rust project offers an npm init template to generate a web application that will call our WebAssembly module. Simply type the command:

# npm init wasm-app www

This will generate the web application inside the www/ directory, including a package.json file, a configuration file for webpack, an empty index.html and an empty JavaScript entrypoint index.js.

To use our WebAssembly package here, we simply add it as a dependency in the package.json file, by adding the following line under the “devDependencies” node:

"hello": "file:../pkg"

Then, install the dependencies with the well known command:

# npm install

Once the installation is finished, modify the index.js file to call our WebAssembly greet() function, with this code:

import * as wasm from "hello"; 
wasm.greet();

This code imports our WebAssembly module using the JavaScript glue code in hello.js, and calls the greet()  function.

As we have Webpack and its local server installed, we can run the application with the command:

# npm run start

Now point your browser to http://localhost:8080/ to be greeted with the message from our Rust code.

Congratulations, you have created your first Rust/WebAssembly project!

Conclusions

There is plenty more to say about Rust and WebAssembly, considering best practice, optimization and interoperation between Rust and JavaScript (look up js-sys and web-sys).

If you want to learn more about Rust and WebAssembly, don’t miss the talk Diwanshi Pandey, software engineer at Red Hat, gave at Codemotion Milan 2019!

Diwanshi addressed more advanced topics and showed some interesting demos.

Tagged as:Codemotion Milan JavaScript

The Convergence of IoT and Blockchain is Transforming Industries
Previous Post
Reactive Amsterdam Community: interview with Fabio Tiriticco
Next Post

Primary Sidebar

Whitepaper & Checklist: How to Organise an Online Tech Conference

To help community managers and companies like ours overcome the Covid-19 emergency we have decided to share our experience organizing our first large virtual conference. Learn how to organise your first online event thanks to our success story – and mistakes!

DOWNLOAD

Latest

What are the Main Areas of Development for Programmers to Land Their Dream Job? Codemotion

What are the Main Areas of Development for Programmers to Land Their Dream Job?

Backend Developer

How to Contribute to an Open-Source Project

How to Contribute to an Open-Source Project

Backend Developer

6 Great DevOps Metrics - and How to Choose the Right Metrics

6 Great DevOps Metrics – and How to Choose the Right Metrics

DevOps Engineer

Codemotion Interview with Chad Arimura

Thinking Like a Founder – meet Chad Arimura

CTO

DesignOps and UX Engineers

Move Over DevOps! Time for DesignOps and UX Engineers

Designer - CXO

Related articles

  • Why Should You Care to Learn TypeScript?
  • GraphQL Testing With Karate
  • Introducing a new and improved Twitter API
  • Speeding up innovation with Arun Gupta
  • 18 Books & Blogs Every Developer Should Read
  • Kick Off A React Project: CRA, Next.js or Gatsby?
  • Tips For Every Full-Stack Developer In 2020
  • Douglas Crockford and his book “How JavaScript works”
  • Shokunin of the Web
  • Douglas Crockford: the good part of JavaScript

Subscribe to our platform

Subscribe

Share and learn. Launch and grow your Dev Community. Join thousands of developers like you and code the future. Together.

Footer

  • Learning
  • Magazine
  • Community
  • Events
  • Kids
  • How to use our platform
  • About Codemotion Magazine
  • Contact us
  • Become a contributor
  • How to become a CTO
  • How to run a meetup
  • Tools for virtual conferences

Follow us

  • Facebook
  • Twitter
  • LinkedIn
  • Instagram
  • YouTube
  • RSS

DOWNLOAD APP

© Copyright Codemotion srl Via Marsala, 29/H, 00185 Roma P.IVA 12392791005 | Privacy policy | Terms and conditions

  • Learning
  • Magazine
  • Community
  • Events
  • Kids
  • How to use our platform
  • About Codemotion Magazine
  • Contact us
  • Become a contributor
  • How to become a CTO
  • How to run a meetup
  • Tools for virtual conferences

Follow us

  • Facebook
  • Twitter
  • LinkedIn
  • Instagram
  • YouTube
  • RSS

DOWNLOAD APP

CONFERENCE CHECK-IN