Getting started with Rust WebAssembly apps for the SAFE Browser


#1

WebAssembly is a recent addition to browsers that enable the use of other languages than JavaScript for writing web apps. Here is a short guide to writing a Hello World application in Rust and getting it running as a SAFE web application.

There is a working demo at safe://hello.webassembly. It only prints “Hello World” in the developer console, so you need to open that to see the message.

First you need to install the Rust language and Emscripten to be able compile your Rust code to WebAssembly.

You can use the following guide for that if you don’t have this installed already.

Once you have installed it, create a directory for the project and place the following in the file hello.rs

fn main() {
println!(“Hello World!”);
}

Then you need to create an index.html file in the same directory with the following content. Replace the url variable that’s set to safe://hello.webassembly with your own url.

<html>
<script>
var Module = {};

function runWebAssembly(appToken, url)
{
  return window.safeApp.webFetch(appToken, url + 'hello.wasm')
  .then(buffer => {
    Module.wasmBinary = buffer;
    var script = document.createElement('script');
    script.src = url + 'hello.js';
    script.onload = function() {
      console.log("Emscripten boilerplate loaded.")
    }
    document.body.appendChild(script);
  });
}

let app = {
  name: 'Hello Webassembly',
  id: 'net.webassembly.tutorial.webapp.example1',
  version: '0.1.0',
  vendor: 'webassembly'
}

function connectAndRun(appToken, funct)
{
  return window.safeApp.connect(appToken)
      .then(_ => funct().then(_ => window.safeApp.free(appToken)));
}

var url = 'safe://hello.webassembly/';

window.safeApp.initialise(app)
  .then((appToken) => connectAndRun(appToken, function(){ return runWebAssembly(appToken, url); }))
  .catch((err) => { console.error("Error from webapp: ", err); })

</script>
</html>

Next you need to compile the Rust code to WebAssembly with the following command

rustc --target=wasm32-unknown-emscripten hello.rs

The files hello.js and hello.wasm was now created by the compiler. hello.wasm is the actual compiled rust code while hello.js is boilerplate javascript code needed to load and run the WebAssembly file.

The last step is to upload index.html , hello.js and hello.wasm to your site, then you should be able to go to your site and see “Hello World” printed in the dev console.

Next I’ll be looking into how to call JavaScript functions from Rust to be able to call the SAFE JavaScript API from the Rust web application and store some data on the SAFE Network.


#2

Just to say, delighted to see this. I keep going to wasm as I am no JS developer and like the idea of missing out my hated FFI layer is possible. I have great hope for this one and will watch with much interest to see how you get on.

Nice one :+1: :+1: :+1:


#3

Wow, this is an eye opener.
Totally uncharted land for me (more or less goes for rust too).
Found this blog post: http://asquera.de/blog/2017-04-10/the-path-to-rust-on-the-web/ which goes into some additional details about it.

I’m wondering, what capabilities does this code have when running in the js VM? It is still shielded off from the host machine, right?

From an outside perspective I get curious also about what the advantages here are, except that rust coders (among others) can use their preferred language for coding web apps (I guess?).


#4

Wow from me too. Very interested to learn this is what web assembly is about - I probably read it already but this rams the point home and hopefully makes it stick! :slight_smile:

Just to add, ‘preferred’ bringing the advantages of Rust as in much less error prone coding and catching errors earlier (at compile time), which will be particularly useful for certain areas of programming.

Not sure of the disadvantages - because possibly you can mix languages, I guess you could still use the many useful libraries and frameworks available in JS? - except perhaps added complexity and maybe small additional load time for simple apps.


#5

It’s no different than js in this regard.

There’s two reasons for web assembly really. One is to enable the use of many different languages and reuse existing code on the web, the other is performance, web assembly can get closer to native performance than javascript.


#6

The main disadvantage is really the same as that of having many different programming languages for desktop/server apps. If everyone just used one single programming languages, certain things would be simpler, everyone just has that one language they need to learn and think about, but the advantages of having many programming languages, rather than just a single one, vastly outweigh this disadvantage.

You can call js code from webassembly and vice versa.


#7

So cool! Thank you for posting.

I tweeted Beaker browser to confirm that web assembly is available for use.

Here I see a WebAssembly object in the Beaker console

Can’t wait to make time to play with this.


#8

Any Windows users whom also want to play, it’s not quite a smooth process to install and utilise Emscripten.
Here’s a guide: https://github.com/hunterlester/rusty_safe_web#emscripten-setup


#9

Take a look at the source code of stdweb.

Also there is this thing called cargo-web which will install emscripten (linux only right now) for you and make rust webdev easier, but there is one downside it only supports asm.js (the predecessor of wasm).

edit: just saw this on “this week in rust”: lord_io/blog/2017/wargo/ (“Sorry, new users can only put 2 links in a post.”)


#10

I tested wargo on a simple bin app in rust, it worked, kinda. You do need to tell llvm to not go through main and complete. In any case it works a bit, but if you then have libs that are not no_std only then there are issues AFAIK. Anyhow wargo is a great try, I see the rust team looking at wasm and agreeing the compiler targets right now are not tier 1 ready at all. So a bit of work to do, but that team will get it, if anyone can.

Interesting to see the c++ emscripten projects have not yet got to create exciting stuff yet, I wish there were movement here, but its for sure very interesting.


#11

native wasm support for rust(work in progress): https://github.com/rust-lang/rust/pull/45905


#12
  1. wasm support got enable: https://github.com/rust-lang/rust/pull/46115
  2. there is a chance for stdweb to support the wasm target without emscripten: https://github.com/koute/stdweb/issues/36