Will WebAssembly Replace JavaScript?

Will WebAssembly Replace JavaScript?

"WebAssembly will replace JavaScript."

I have read this so many times on these internet streets, and that has made me curious about the possibility of making full-stack web applications with WebAssembly.

First, to calm your nerves, it is currently not possible to use WebAssembly in the browser for web applications without some JavaScript glue code (more on "glue code" later). But there are a lot of things you can already do in the browser with WebAssembly, which you could only do with JavaScript in the past.

How about I take you on a journey, as we explore WebAssembly, and how you can take advantage of its features as a JavaScript developer? Most of the things discussed also extend to Rustaceans, Gophers, Pythonians, and whatever C++ developers are called. At the end of this article, I will also show you how you can hook up a small JavaScript script to a WASM binary and execute a simple Rust program. So come along as we explore...

WebAssembly? What?

WebAssembly, or WASM for short, is a new technology that has been gaining a lot of attention in recent years. It is a low-level, binary instruction format for a stack-based virtual machine (VM). It is designed as a portable target for the ahead-of-time (AOT) compilation of high-level languages such as C, C++, and Rust, enabling deployment on the web for client-side and server-side applications.

Okay, that feels like a lot of buzzwords. In simpler terms:

WebAssembly is a fancy new virtual machine that now ships with all web browsers - well almost all browsers (looking at you Internet Explorer 11 and Opera Mini! - that allows you to run performance-critical business-logic code at blazingly-fast speed. Of course, we can put a lot of logic in our JavaScript frontends using our trusty client-side rendering frameworks, or we can just put our logic in a Node.js backend and communicate with it from the front end using APIs, right?

Five.Co - What is WebAssembly?

I Can Write My Logic in JavaScript

Well yes, and that is how it has been done before WebAssembly joined the party, but remember when I said "performance-critical" business logic? WebAssembly does not advertise itself as another scripting environment to make buttons animate or submit forms but as an alternative for running heavy workloads at near-native speed. Remember when app developers would say "web browsers will never run progressive web apps (PWAs) as fast as native applications"? Well, not quite so anymore.

The problem with using a dynamically-typed interpreted programming language (JavaScript) for writing business logic for performance-critical applications is that it's just plain difficult to achieve any decent performance or to even get it running in the browser at all.

With WebAssembly, you can perform complex computations at near-native speeds. JavaScript is a dynamically typed, interpreted language, which means that it can be slow when performing complex operations. WebAssembly, being a statically typed, compiled language, allows complex computations to run much faster than JavaScript. This makes WebAssembly a great option for tasks such as video rendering, 3D graphics, and other computationally intensive operations.

SECURITY

WebAssembly allows for improved security and sandboxing. JavaScript is a high-level language and is executed by the browser's JavaScript engine, which can be vulnerable to attacks. WebAssembly, on the other hand, is executed by the browser's WebAssembly engine, which is more secure and can be sandboxed to prevent malicious code from running. This makes WebAssembly a great option for web-based tasks such as online banking, payment processing, online gaming, and secure document signing, which require a high level of security.

WebAssembly invites C, C++, Rust, Go, and others to the browser party!!!

The best thing about WebAssembly is its ability to interact with other programming languages. WebAssembly modules can be written in any language that can be compiled to WebAssembly bytecode, such as C, C++, Rust, and more. This allows developers to use their preferred language for a specific task, and then seamlessly integrate it into a web application using WebAssembly. This can be especially useful for developers who are already familiar with a particular language and want to use it for web development.

Should You Be Concerned?

For some JavaScript developers, the rise of WebAssembly may seem like a daunting prospect. As more and more web frameworks written in programming languages like Rust, Go, and C++ are developed, it becomes increasingly easy for developers to write frontends in languages other than JavaScript.

Admittedly, for other JavaScript developers, WebAssembly might be a welcome respite from JavaScript's complex syntax and idiosyncracies.

Five.Co - JS & WASM

One example of a framework that utilizes WebAssembly is Yew, a modern Rust framework for creating web apps. Yew allows developers to write safe and performant code that can be compiled to WASM and run directly in the browser. This means that Rust developers can now build web apps without having to learn JavaScript.

Another example is GopherJS, a transpiler that allows developers to write front-end code in Go and then compile it to JavaScript. This means that Go developers can also build web apps without having to learn JavaScript.

Similarly, C++ developers can now use the C++ WebAssembly Framework (CWasm) to build web apps. CWasm is a C++ library that provides a C++ interface to the WebAssembly virtual machine, making it easy for C++ developers to write web apps that run on the browser.

Inside Five, our low-code environment, application logic can be written in JavaScript or TypeScript. So far, so plain vanilla web development. However, Five is designed to support WASM. This means that in the future, developers will be able to write code in any language that compiles to WASM right inside of Five's code editor, whether that's C#, Python or Rust.

The emergence of these frameworks and solutions indicates that WebAssembly is becoming a viable alternative to JavaScript for front-end web development. This is a scary prospect for JavaScript developers as it means that their skills may become less in demand in the future.

However, it is important to note that JavaScript is still the most widely-used programming language on the web and it is unlikely to be replaced entirely by WebAssembly. Instead, WebAssembly will likely be used to complement and enhance the capabilities of JavaScript.

Getting started - Running a WASM binary with JavaScript

You know I can't leave you without some code. Let's try to write a simple WASM binary written in six lines of Rust, and then run it in a web browser using only 11 lines of JavaScript. I also added a link to an already compiled WASM binary in case you don't want to write six lines of Rust.

Here is a step-by-step guide:

1. Install Rust

You can install Rust using the rustup script. Just run the below in your terminal:

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

2. Install wasm-pack

wasm-pack is the Rust library that we will use to compile Rust into WASM.

If you installed Rust, then you already have Cargo installed. Run the following to install wasm-pack:

cargo install wasm-pack

3. Create a new Rust project

Next, you need to create a new Rust project. Run the following command in your terminal to create a new Rust project with the name "wasm_example":

cargo new --lib wasm_example

4. Update Cargo.toml

After that, you need to add the wasm-bindgen library to your Cargo.toml file, which was generated by Cargo. This library will allow you to interact with JavaScript in your Rust code. Add the following line to your Cargo.toml file in the dependencies section:

wasm-bindgen = "0.2"

Your Cargo.toml should look like this:

[package]

name = "wasm_example"

version = "0.1.0"

edition = "2021"

[lib]

crate-type = ["cdylib", "rlib"]

[dependencies]

wasm-bindgen = "0.2"

Don't forget to add:

[lib]

crate-type = ["cdylib", "rlib"]

as demonstrated above.

5. Six lines of Rust

Now, you need to write your Rust code. In the src directory, open the lib.rs file and write your Rust code. We want a very simple Add function that takes two integers as arguments and returns their sum:

use wasm_bindgen::prelude::wasm_bindgen;

#[wasm_bindgen]

pub fn add(left: usize, right: usize) -> usize {

left + right

}

6. Build it!

Next, you need to use the wasm-pack tool to compile your Rust code to WebAssembly. Run the following command in your terminal:

wasm-pack build

Once the compilation is complete, you will find a pkg directory in your project. Inside the pkg directory, you will find some JavaScript files and a WebAssembly file.

7. JavaScript Glue Code

Now you will need to write a JavaScript file that will interact with your WASM code. Create a new file glue.js in your project directory and write the following in it:

// Load the WebAssembly module

const importObject = {};

const path_to_wasm = "./pkg/wasm_example_bg.wasm";

fetch(path_to_wasm)

.then(response => response.arrayBuffer())

.then(bytes => WebAssembly.instantiate(bytes, importObject))

.then(results => {

const wasm = results.instance.exports;

// Call a function exported by the WebAssembly module

console.log(wasm.add(20, 4));

});

8. HTML

To run anything in the browser, we need an HTML file. Create a new file index.html in your project directory and write the following in it:

<!DOCTYPE html>

<html>

<head>

<title>WASM example</title>

<script src="./glue.js"></script>

</head>

<body>

</body>

</html>

9. SHIP IT!!!

To run it in your browser, you could just open the HTML file in your browser, but you might encounter some CORS issues, so I'll recommend you use a simple tool called "http-server" to serve your static files. If you have nodejs installed, you can install it using:

npm install http-server -g

Now that you have it installed, simply run http-server in your project directory and you will be given a URL that you can open in your browser.

10. Test it!

You see a blank screen and you wonder why? Well, remember we didn't write anything fancy in our HTML file? We need to open the console of the browser to see the result of our addition.

If everything worked fine, you should see a number printed in the console, which should be the sum of the two numbers we passed to the function in glue.js at console.log(wasm.add(20, 4));. you can change these numbers to get a different sum. Congratulations! You just made your first WASM project!

If you change the numbers and you still get the same number printed in the console, it is because your browser is caching the JavaScript. You can force-reload the page by holding shift and hitting the refresh button while the console is open.

All of the code is in this Github repository. Feel free to use it and play with it.

In case you hate Rust or don't want to write Rust code, no worries. I have compiled the Rust code for the JS devs to play with. The output of the wasm-pack build command is located in the pkg folder in the above repository. Thank me later!

Conclusion

WebAssembly is a powerful new technology that has the potential to supplement and enhance the capabilities of JavaScript. While it is unlikely that JavaScript will be completely replaced by WebAssembly, it can be used to perform complex computations at near-native speeds, interact with other programming languages, and provide improved security and sandboxing. As web development continues to evolve, it is likely that WebAssembly will play an increasingly important role in the development of web applications. Developers who are looking to expand their skills and stay ahead of the curve should consider learning WebAssembly and experimenting with its capabilities.

To learn more about WebAssembly and how it relates to low-code development, check out our blog post.

Thanks for reading, and see you in the next one!


This blog post was contributed by 0xHiro. Find Hiro on GitHub or Twitter here.

Originally published at https://five.co/will-webassembly-replace-javascript/ on February 23, 2023.