# What is Second State?

WebAssembly for cloud services

## This page is outdated. Please [visit here for the most up-to-date content](https://www.secondstate.io/articles/why-webassembly-server/).

Second State builds the next generation open source “operating system” for the cloud and the decentralized web. The Second State Virtual Machine (SSVM) is a WebAssembly runtime optimized for server-side applications. It works seamlessly with existing application frameworks, such as Node.js, but provides a secure and lightweight runtime at native performance. It is a managed alternative to native code, and is ideal for building AI and big data microservices. [Check out why](/server-side-webassembly/why) you want to use WebAssembly on the server-side.

{% hint style="info" %}
Node.js and Rust developers [get started here](/server-side-webassembly/getting-started)! Create high performance Rust + JavaScript hybrid apps in Node.js.
{% endhint %}

The SSVM also powers decentralized applications as the execution engine for leading public blockchains, such as [Ethereum 2.0](https://blog.secondstate.io/post/20191022-soll-compiler-project/), [Ethereum Classic](https://blog.secondstate.io/post/20190901-etc-partners-with-secondstate/), [Polkadot / Web3](https://blog.secondstate.io/post/20200302-polkadot-en/), [Oasis](https://www.coindesk.com/a16z-leads-45-million-raise-for-blockchain-startup-oasis-labs), and [CyberMiles](https://docs.secondstate.io/buidl-developer-tool/getting-started/develop-for-cybermiles). If you are interested in our blockchain-related technologies, [check out here](https://docs.secondstate.io).

Second State is a Venture Capital backed startup with offices in USA, Taiwan, China, and Australia.


# Why?

WebAssembly could improve security and efficiency of web services

## This page is outdated. Please visit here to check out [Why WebAssembly on the server-side](https://www.secondstate.io/articles/why-webassembly-server/).

{% embed url="<https://www.youtube.com/watch?v=RjYLHxNO4nM>" %}

You can bootstrap a WebAssembly virtual machine from your server side application, such as a Node.js app, and then execute high performance and potentially unsafe code inside the virtual machine. The major use cases are web applications that require native performance or must execute user-submitted code.

{% hint style="info" %}
Node.js and Rust developers [get started here](/server-side-webassembly/getting-started)! Create high performance Rust + JavaScript hybrid apps on Node.js.
{% endhint %}

**Native code** is often used where high performance and efficiency are required. The popular Node.js runtime is written in native C/C++. Native code runs AI inference, big data analytics, image and video processing, and scientific computing. WebAssembly is a light, fast, and cross-platform container. It is a safe and managed alternative to native code. [Learn more here](https://medium.com/wasm/webassembly-on-the-server-side-c584f874b4a3).

**User submitted code** is the cornerstone of cloud native or serverless computing. For SaaS providers, users want to customize their experiences using code, or to create applications for their peers. Examples include Function as a Service, workflow apps, smart contracts, plugins, and extensions. WebAssembly supports multiple programming languages, and can provide a high performance sandbox for user submitted code with little resource consumption.

[Second State](https://www.secondstate.io/) provides an open source WebAssembly implementation (Second State Virtual Machine, or [SSVM](https://github.com/second-state/SSVM)) that is specifically optimized for server side applications. It is

* High performance with support for JIT and AOP optimizations.
* Seamlessly supports server application frameworks, such as NodeJS. You can build high performance NodeJS apps with SSVM.
* Supports safe access to external resources, such as databases, message queues, and even new AI hardware
* Allows precise metering of computational resources for serverless apps.

Visit our [web site](https://www.secondstate.io/) or follow us on social media \[[Twitter](https://twitter.com/secondstateinc), [LinkedIn](https://www.linkedin.com/company/second-state/), and [Medium](https://medium.com/wasm)], and learn how WebAssembly could improve your web applications and services!


# WebAssembly vs native code

How can WebAssembly and Rust programs benefit your web and services application

## This page is outdated. Please visit here to check out [WebAssembly vs native code](https://www.secondstate.io/articles/webassembly-vs-native-code/).

WebAssembly aims to drastically improve your application performance, safety, and developer productivity. It replaces native code with a managed container and finely grained security model.&#x20;

{% embed url="<https://youtu.be/dxnTNe6Nmpw>" %}

#### **Why do we program in native code in 2020?**

In the past several years, CPU speed has pretty much stopped improving. At the same time, AI, big data, and blockchain have all create huge demands for more computing power. So far, the solution has been more and more native code in our software. Native code is efficient, close to the hardware, and can access specialized hardware such as GPU and AI chips.

However, native code also has issues such as platform dependency and safety. The big trend in software engineering in the past 30 years has been to move away from native code into managed code running inside virtual machines or containers.

#### **How exactly is WebAssembly better than native code?**

WebAssembly is the next-generation virtual machine that will help us turn native code modules into managed services.

* WebAssembly programs can be **written in multiple programming languages**, not just C and C++. In particular, Rust is well supported on WebAssembly.
* WebAssembly programs can be **accessed or invoked from multiple programming frameworks**, such as JavaScript, Python, and PHP.
* WebAssembly programs are **cross-platform**. They can run without change on all major operating systems and hardware platforms.
* WebAssembly programs are **safe** as they are executed inside a virtual machine.
* WebAssembly programs are **highly efficient** and very fast due to its lightweight virtual machine design. It is on par with native code performance.
* WebAssembly provides an easy and secure **extension mechanism to access new hardware**.

#### **WebAssembly is safe, very fast, language-agnostic, and platform-independent. But, isn’t WebAssembly mostly used inside the web browser?**

WebAssembly started as a collaboration between Google, Mozilla, Apple, and Microsoft. It was envisioned to be a high-performance code execution engine inside browsers. The typical applications would be in-browser animated games that require performance, much like the Java Applet from the old days.

{% embed url="<https://youtu.be/R7WB3gmtku8>" %}

However, like Java and JavaScript before it, WebAssembly is finding success on the server-side. WebAssembly’s safety, performance, platform, and language independence, make it an ideal server-side runtime.

#### **Is it true that one must learn Rust in order to use WebAssembly?**

No. WebAssembly is language agnostic. You can invoke WebAssembly programs and functions from a variety of different host languages, such as Javascript, Rust, Go, Python or even PHP.

You can also write WebAssembly programs in a variety of different programming languages. However, it is also true that Rust is currently the most widely used language to create WebAssembly programs and modules.

Rust has been voted the most beloved programming language for the past 4 years in a row. It is the hottest programming language right now. It has many exciting features. For example, it is powerful and flexible like C, but much safer and without Java’s performance overhead. It supports both object-oriented and functional programming paradigms. It is one of the fastest-growing programming languages in the world and is now used in the entire software stack from front end to backend to infrastructure.


# Getting started

High-performance Rust functions in Node.js

## This page is outdated. Please visit here to [see how to run Rust functions in Node.js](https://www.secondstate.io/articles/getting-started-with-rust-function/).

There are great use cases for [WebAssembly on the server-side](/server-side-webassembly/why), especially for AI, blockchain, and big data applications. In this tutorial, I will show you how to incorporate WebAssembly functions, written in Rust, into Node.js applications on the server. This approach combines Rust's ***performance***, WebAssembly's ***security and portability***, and JavaScript's ***ease-of-use***. A typical Rust + Node.js hybrid app works like this.

* The host application is a Node.js web application written in JavaScript. It makes WebAssembly function calls.
* The WebAssembly bytecode program is written in Rust. It runs inside the SSVM, and is called from the Node.js web application.

{% hint style="success" %}
The source code of the tutorial is [here](https://github.com/second-state/wasm-learning/tree/master/nodejs/hello). If you just want to try it out, you can [fork this repository](https://github.com/second-state/ssvm-nodejs-starter/fork) and [use the VSCode IDE to open it](/server-side-webassembly/getting-started/the-no-software-approach).
{% endhint %}

## Prerequisites

Since we are building Rust functions to run in Node.js, make sure that you have [Rust](https://www.rust-lang.org/tools/install) and [Node.js](https://nodejs.org/en/download/package-manager/) installed on your computer.

## **Setup**

> We use the Second State Virtual Machine (SSVM) , an open source WebAssembly runtime [optimized for server-side applications](/server-side-webassembly/performance), together with Node.js.

The [ssvm](https://www.npmjs.com/package/ssvm) and [ssvmup](https://www.npmjs.com/package/ssvmup) npm modules install the [Second State Virtual Machine (SSVM)](https://github.com/second-state/ssvm) into Node.js as a native addon, and provides the necessary compiler tools. [Learn more](/server-side-webassembly/getting-started/the-ssvmup-tool) about the [ssvmup](https://github.com/second-state/ssvmup) tool.

```
# Install ssvmup toolchain
$ npm install -g ssvmup # Append --unsafe-perm if permission denied

# Install the nodejs addon for SSVM
$ npm install ssvm
```

## **WebAssembly program in Rust**

In this example, our Rust program appends the input string after “hello”. Below is the content of the Rust program [`src/lib.rs`](https://github.com/second-state/ssvm-nodejs-starter/blob/master/src/lib.rs). You can define multiple external functions in this library file, and all of them will be available to the host JavaScript app via WebAssembly. Just remember to annotate each function with `#[wasm_bindgen]` so that [ssvmup](https://github.com/second-state/ssvmup) knows to generate the correct JavaScript to Rust interface for it when you build it.

```
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn say(s: String) -> String {
  let r = String::from("hello ");
  return r + &s;
}
```

Next, you can compile the Rust source code into WebAssembly bytecode and generate the accompanying JavaScript module for the Node.js host environment.

```
$ ssvmup build
```

The result are files in the `pkg/` directory. the `.wasm` file is the WebAssembly bytecode program, and the `.js` files are for the JavaScript module.

## **The Node.js host application**

Next, go to the `node` folder and examine the JavaScript program [`app.js`](https://github.com/second-state/ssvm-nodejs-starter/blob/master/node/app.js). With the generated `hello_lib.js` module, it is very easy to write JavaScript to call WebAssembly functions. Below is the node application `app.js`. It simply imports the `say()` function from the generated module. The node application takes the `name` parameter from incoming an HTTP GET request, and responds with “hello `name`”.

```
const { say } = require('../pkg/hello_lib.js');

const http = require('http');
const url = require('url');
const hostname = '127.0.0.1';
const port = 8080;

const server = http.createServer((req, res) => {
  const queryObject = url.parse(req.url,true).query;
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end(say(queryObject['name']));
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});
```

Start the Node.js application server as follows.

```
$ node app.js
Server running at http://127.0.0.1:8080/
```

Then, you can test it.

```
$ curl http://127.0.0.1:8080/?name=Wasm
hello Wasm
```

## **More complex examples**

Besides passing string values between Rust and JavaScript, the ssvmup tool supports the following data types.

* Rust call parameters can be any combo of `i32`, `String`, `&str`, `Vec<u8>`, and `&[u8]`
* Return value can be `i32` or `String` or `Vec<u8>`
* For complex data types, such as structs, you could use JSON strings to pass data.&#x20;

{% hint style="info" %}
With JSON support, you can [call Rust functions with any number of input parameters and return any number of return values of any type](/server-side-webassembly/pass-any-argument-and-return-any-value).
{% endhint %}

The Rust program [`src/lib.rs`](https://github.com/second-state/wasm-learning/blob/master/nodejs/functions/src/lib.rs) in the [functions example](https://github.com/second-state/wasm-learning/tree/master/nodejs/functions) demonstrates  how to pass in call arguments in various supported types, and return values.

```
#[wasm_bindgen]
pub fn obfusticate(s: String) -> String {
  (&s).chars().map(|c| {
    match c {
      'A' ..= 'M' | 'a' ..= 'm' => ((c as u8) + 13) as char,
      'N' ..= 'Z' | 'n' ..= 'z' => ((c as u8) - 13) as char,
      _ => c
    }
  }).collect()
}

#[wasm_bindgen]
pub fn lowest_common_denominator(a: i32, b: i32) -> i32 {
  let r = lcm(a, b);
  return r;
}

#[wasm_bindgen]
pub fn sha3_digest(v: Vec<u8>) -> Vec<u8> {
  return Sha3_256::digest(&v).as_slice().to_vec();
}

#[wasm_bindgen]
pub fn keccak_digest(s: &[u8]) -> Vec<u8> {
  return Keccak256::digest(s).as_slice().to_vec();
}
```

Perhaps the most interesting is the `create_line()` function. It takes two JSON strings, each representing a `Point` struct, and returns a JSON string representing a `Line` struct. Notice that both the `Point` and `Line` structs are annotated with `Serialize` and `Deserialize` so that the Rust compiler automatically generates necessary code to support their conversion to and from JSON strings.

```
use wasm_bindgen::prelude::*;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug)]
struct Point {
  x: f32, 
  y: f32
}

#[derive(Serialize, Deserialize, Debug)]
struct Line {
  points: Vec<Point>,
  valid: bool,
  length: f32,
  desc: String
}

#[wasm_bindgen]
pub fn create_line (p1: &str, p2: &str, desc: &str) -> String {
  let point1: Point = serde_json::from_str(p1).unwrap();
  let point2: Point = serde_json::from_str(p2).unwrap();
  let length = ((point1.x - point2.x) * (point1.x - point2.x) + (point1.y - point2.y) * (point1.y - point2.y)).sqrt();

  let valid = if length == 0.0 { false } else { true };
  let line = Line { points: vec![point1, point2], valid: valid, length: length, desc: desc.to_string() };
  return serde_json::to_string(&line).unwrap();
}

#[wasm_bindgen]
pub fn say(s: &str) -> String {
  let r = String::from("hello ");
  return r + s;
}
```

Next, let's examine the JavaScript program [`app.js`](https://github.com/second-state/wasm-learning/blob/master/nodejs/functions/node/app.js). It shows how to call the Rust functions. As you can see `String` and `&str` are simply strings in JavaScript, `i32` are numbers, and `Vec<u8>` or `&[8]` are JavaScript `Uint8Array`. JavaScript objects need to go through `JSON.stringify()` or `JSON.parse()` before being passed into or returned from Rust functions.

```
const { say, obfusticate, lowest_common_denominator, sha3_digest, keccak_digest, create_line } = require('./functions_lib.js');

var util = require('util');
const encoder = new util.TextEncoder();
console.hex = (d) => console.log((Object(d).buffer instanceof ArrayBuffer ? new Uint8Array(d.buffer) : typeof d === 'string' ? (new util.TextEncoder('utf-8')).encode(d) : new Uint8ClampedArray(d)).reduce((p, c, i, a) => p + (i % 16 === 0 ? i.toString(16).padStart(6, 0) + '  ' : ' ') + c.toString(16).padStart(2, 0) + (i === a.length - 1 || i % 16 === 15 ?  ' '.repeat((15 - i % 16) * 3) + Array.from(a).splice(i - i % 16, 16).reduce((r, v) => r + (v > 31 && v < 127 || v > 159 ? String.fromCharCode(v) : '.'), '  ') + '\n' : ''), ''));

console.log( say("SSVM") );
console.log( obfusticate("A quick brown fox jumps over the lazy dog") );
console.log( lowest_common_denominator(123, 2) );
console.hex( sha3_digest(encoder.encode("This is an important message")) );
console.hex( keccak_digest(encoder.encode("This is an important message")) );

var p1 = {x:1.5, y:3.8};
var p2 = {x:2.5, y:5.8};
var line = JSON.parse(create_line(JSON.stringify(p1), JSON.stringify(p2), "A thin red line"));
console.log( line );
```

After running ssvmup to build the Rust library, running `app.js` in Node.js environment produces the following output.

```
$ ssvmup build
... Building the wasm file and JS shim file in pkg/ ...

$ node app.js
hello SSVM
N dhvpx oebja sbk whzcf bire gur ynml qbt
246
000000  57 1b e7 d1 bd 69 fb 31 9f 0a d3 fa 0f 9f 9a b5  W.çÑ½iû1..Óú...µ
000010  2b da 1a 8d 38 c7 19 2d 3c 0a 14 a3 36 d3 c3 cb  +Ú..8Ç.-<..£6ÓÃË

000000  7e c2 f1 c8 97 74 e3 21 d8 63 9f 16 6b 03 b1 a9  ~ÂñÈ.tã!Øc..k.±©
000010  d8 bf 72 9c ae c1 20 9f f6 e4 f5 85 34 4b 37 1b  Ø¿r.®Á .öäõ.4K7.

{ points: [ { x: 1.5, y: 3.8 }, { x: 2.5, y: 5.8 } ],
  valid: true,
  length: 2.2360682,
  desc: 'A thin red line' }
```

## **What’s next?**

Now we have seen a very simple example to call a Rust function from JavaScript in a Node.js application. [In the next article,](/server-side-webassembly/pass-any-argument-and-return-any-value) we will discuss how to pass arbitrary arguments from a JavaScript program to Rust.


# VS Codespaces

Get started with Rust functions in Node.js app without installing any software

## This page is outdated. Please visit here to check out [how to get started with Rust functions in Node.js with VSCode](https://www.secondstate.io/articles/getting-started-rust-nodejs-vscode/).&#x20;

In the [previous tutorial](/server-side-webassembly/getting-started), we discussed how to create and access Rust functions in Node.js apps. In this tutorial, I will show you how to experiment with development without installing any developer tools software.

![https://www.youtube.com/watch?v=j85cbNsciOs](/files/-M7ih1C5kjt59UNOXtDf)

[**Fork this GitHub repository**](https://github.com/second-state/ssvm-nodejs-starter/fork) to get started. In your fork, you can use GitHub's web UI to edit source code files.

* The Rust files are in the `src` directory. You can put high performance workload into Rust functions. The Rust build and dependency configuration is in the `Cargo.toml` file.
* The JavaScript files are in the `node` directory and they can access the Rust functions.
  * The `node/app.js` file contains the application.

### VS Codespaces steps

{% hint style="info" %}
VS Codespaces runs entirely in your browser and costs around $1 per work day. It is cheaper than a cup of coffee in the office. Alternatively, in steps 1-2 below, you could use locally installed VSCode and Docker, and [launch the IDE with your remote git repository](https://code.visualstudio.com/remote-tutorials/containers/getting-started).
{% endhint %}

First, open the [VSCode Codespaces](https://online.visualstudio.com/) web site and login with your Azure account. You can get a [free Azure account](https://azure.microsoft.com/en-us/free/).

Next, create a new codespace. Put your forked repository into the Git Repository field. This step takes a few minutes. But once a codespace is created, subsequent openings only take seconds.

![](/files/-M6rgrDU19q3AwK5HTIT)

Open the source code files and make changes as you wish!

![](/files/-M6rh4uRU1jlyhbgogfo)

Click on the Run button on the left panel, and then the Launch Program at the top to build and run the application.

![](/files/-M6rhEyyc0F-Xi_QULSy)

The Terminal window at the bottom shows the build progress. It builds the Rust program, and then launches the Node.js app.

![](/files/-M6rhQPQv2cLxLEUdwf3)

The Debug window shows the Node.js server running and waiting for web requests.

![](/files/-M6rh_DgonJ4jp6rJlQj)

Now, open another terminal window in the IDE via the `Terminal -> New Terminal` menu.

![](/files/-M6rhzSfSE03tmFm5Fr3)

From the terminal window, you can test the local server.

```
$ curl http://127.0.0.1:3000/?name=SSVM
hello SSVM
```

In fact, you can run any Linux command from VSCode's built-in Terminal. You could run `ssvmup build` to build, and then `node node/app.js` to run the Node.js application. The Node.js application could be a server application as we have shown here, or simply a command line program as many of our [later examples](/server-side-webassembly/pass-any-argument-and-return-any-value).

![](/files/-M6rkkwZ6dvOgEohgF67)

That's it! VSCode has many useful features such as real time error detection and syntax highlighting as you type code, advanced Github integration, and integrations with many many development tools. Enjoy coding!


# The ssvmup tool

The compiler toolchain for Rust functions in JavaScript

## This page is outdated. Please visit here to learn how the [ssvmup tool ](https://www.secondstate.io/articles/ssvmup/)work.

Throughout our examples, we make extensive use of the [ssvmup](https://github.com/second-state/ssvmup) tool. It is inspired by the wasm-pack project but is optimized for server-side applications. Specifically, it supports the [SSVM](https://github.com/second-state/ssvm) WebAssembly virtual machine and Deno host runtime.

The [ssvmup](https://github.com/second-state/ssvmup) uses `wasm-bindgen` to automatically generate the “glue” code between JavaScript and Rust source code so that they can communicate using their native data types. Without it, the function arguments and return values would be limited to very simple types (i.e., 32-bit integers) supported natively by WebAssembly. For example, [strings or arrays would not be possible](https://medium.com/wasm/strings-in-webassembly-wasm-57a05c1ea333) without [ssvmup](https://github.com/second-state/ssvmup) and `wasm-bindgen`.

The easiest way to install [ssvmup](https://github.com/second-state/ssvmup) is through [NPM](https://www.npmjs.com/package/ssvmup).

```
$ npm install -g ssvmup # Append --unsafe-perm if permission denied
```

You could also install [ssvmup](https://github.com/second-state/ssvmup) as a standalone tool for runtimes such as Deno. You need to have Rust installed before running the command below.

```
$ curl https://raw.githubusercontent.com/second-state/ssvmup/master/installer/init.sh -sSf | sh
```

Next, [learn how](/server-side-webassembly/getting-started) to use ssvmup to build Rust functions for Node.js and Deno applications.


# Rust functions in Node.js

Calling any Rust function from Node.js JavaScript code

## This page is outdated. Please visit here to see how to [call any Rust functions from Node.js JavaSrcipt code](https://www.secondstate.io/articles/rust-functions-in-nodejs/). &#x20;

With JSON support, JavaScript code can call Rust functions with any number of input parameters and return any number of return values of any type. That allows us to take advantage of a large number of Rust libraries and crates in the ecosystem.

{% hint style="success" %}
The source code of the tutorial is [here](https://github.com/second-state/wasm-learning/tree/master/nodejs/json_io).
{% endhint %}

## **WebAssembly program in Rust**

In the `cargo` project called `json_io`, edit the `Cargo.toml` file to add a `[lib]` section and a `[dependencies]` section. Besides the `wasm-bindgen` dependency, notice the `serde` and `serde_json` dependencies. They allow us to serialize and deserialize complex Rust types to and from JSON strings, so that the data can be passed to and from JavaScript.

```
[lib]
name = "json_io_lib"
path = "src/lib.rs"
crate-type =["cdylib"]

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
wasm-bindgen = "=0.2.61"
```

Below is the content of the Rust program `src/lib.rs`. It shows four functions.

* The `circumference()` function takes one floating point number parameter, and returns a floating number value. **Notice** that the floating number type is **not** natively supported in SSVM, but is supported here via JSON.
* The `area()` function takes two floating point numbers (the width and length of a rectangle) and returns a floating point number (the area of the rectangle).
* The `solve()` function takes three floating point numbers (parameters of a quadratic equation), and returns two floating point numbers and a boolean (the roots or solutions to the equation and whether the equation has real roots).
* The `draw()` function takes two structs (`Point`) and a string, and returns a struct (`Line`).

Inside each Rust function, we first deserialize the input JSON string into a tuple, which contains the call arguments of various types. The return values are constructed into a tuple first and then serialized into a JSON string and then returned.

```
use wasm_bindgen::prelude::*;
use serde::{Serialize, Deserialize};

#[wasm_bindgen]
pub fn circumference(radius: &str) -> String {
  let r: f32 = serde_json::from_str(radius).unwrap();
  let c = 2. * 3.14159 * r;
  return serde_json::to_string(&c).unwrap();
}

#[wasm_bindgen]
pub fn area(sides: &str) -> String {
  let s: (f32, f32) = serde_json::from_str(&sides).unwrap();
  let a = s.0 * s.1;
  return serde_json::to_string(&a).unwrap();
}

#[wasm_bindgen]
pub fn solve(params: &str) -> String {
  let ps: (f32, f32, f32) = serde_json::from_str(&params).unwrap();
  let discriminant: f32 = (ps.1 * ps.1) - (4. * ps.0 * ps.2);
  let mut solution: (f32, f32, bool) = (0., 0., false);
  if discriminant >= 0. {
    solution.0 = (((-1.) * ps.1) + discriminant.sqrt()) / (2. * ps.0);
    solution.1 = (((-1.) * ps.1) - discriminant.sqrt()) / (2. * ps.0);
    solution.2 = true;
  }
  return serde_json::to_string(&solution).unwrap();
}
```

The `draw()` example is the same as the `draw_line()` example from the last article, but the input argument is structured into a single JSON tuple.

```
#[derive(Serialize, Deserialize, Debug)]
struct Point {
  x: f32,
  y: f32
}

#[derive(Serialize, Deserialize, Debug)]
struct Line {
  points: Vec<Point>,
  valid: bool,
  length: f32,
  desc: String
}

#[wasm_bindgen]
pub fn draw(points: &str) -> String {
  let ps: (Point, Point, String) = serde_json::from_str(&points).unwrap();
  let length = ((ps.0.x - ps.1.x) * (ps.0.x - ps.1.x) + (ps.0.y - ps.1.y) * (ps.0.y - ps.1.y)).sqrt();

  let valid = if length == 0.0 { false } else { true };
  let line = Line { points: vec![ps.0, ps.1], valid: valid, length: length, desc: ps.2 };
  return serde_json::to_string(&line).unwrap();
}
```

Next, you can compile the Rust source code into WebAssembly bytecode and generate the accompanying JavaScript module for the Node.js host environment.

```
$ ssvmup build
```

The result are files in the `pkg/` directory. the `.wasm` file is the WebAssembly bytecode program, and the `.js` files are for the JavaScript module.

## **The Node.js host application**

Next, go to the `node` folder and examine the JavaScript program `app.js`. It shows how to call the Rust functions. You will first need to construct the call arguments into a JavaScript array (tuple), and then pass the serialized JSON string to the Rust function. The Rust return value is deserialized into a tuple of values as well.

```
const { circumference, area, solve, draw } = require('../pkg/json_io_lib.js');

var x = 10.;
console.log( circumference(JSON.stringify(x)) );

var x = [10., 5.];
console.log( area(JSON.stringify(x)) );

var x = [2., 5., -3.];
console.log( solve(JSON.stringify(x)) );

var x = [{x:1.5, y:3.8}, {x:2.5, y:5.8}, "A thin red line"];
console.log( draw(JSON.stringify(x)) );
```

Run `app.js` in Node.js environment as follows.

```
$ node app.js
62.831802
50.0
[0.5,-3.0,true]
{"points":[{"x":1.5,"y":3.8},{"x":2.5,"y":5.8}],"valid":true,"length":2.2360682,"desc":"A thin red line"}
```

## **What’s next?**

With JSON support, we can call any Rust function from JavaScript. The Rust function, however, often requires access to system resources outside of the WebAssembly VM, such as random numbers, persistent data storage, and network services. We will show you how to accomplish this in the next several articles.


# Access system resources

How to access resources outside of the WebAssembly sandbox

## This page is outdated. Please [visit here for the most up-to-date content](https://www.secondstate.io/tags/rust-function-in-nodejs/).

The WebAssembly VM provides a sandbox to ensure application safety. However, this sandbox is also a very limited "computer" that has no concept of file system, network, or even a clock or timer. That is very limiting for the Rust programs running inside WebAssembly.

In the Second State VM (SSVM), our innovation is a set of standard and proprietary (still open source) extensions that allow WebAssembly bytecode applications to access system and external resources. Read on!

{% content-ref url="/pages/-M7M6RD14rEGIgzAbGhw" %}
[WASI](/server-side-webassembly/enterprise-webassembly/wasi)
{% endcontent-ref %}

{% content-ref url="/pages/-M5cSMvnh751Sl7TfQum" %}
[The storage interface](/server-side-webassembly/enterprise-webassembly/the-storage-interface)
{% endcontent-ref %}

{% content-ref url="/pages/-M5cUymL6zGnSmxHgbHz" %}
[The inference interface](/server-side-webassembly/enterprise-webassembly/the-inference-hardware-interface)
{% endcontent-ref %}


# WASI

Access system resources, such as random numbers, file system, and network from WebAssembly applications

## This page is outdated. Please visit here to see how to [access system resources from WebAssembly](https://www.secondstate.io/articles/wasi-access-system-resources/).

{% hint style="info" %}
If WASM+WASI existed in 2008, we wouldn't have needed to created Docker. That's how important it is. Webassembly on the server is the future of computing. A standardized system interface was the missing link. Let's hope WASI is up to the task! ***-- Solomon Hykes, Co-founder of Docker***
{% endhint %}

The WebAssembly Systems Interface (WASI) is a standard extension for WebAssembly bytecode applications to make operating system calls. It is fully supported in the SSVM. WASI defines a set of function names to perform operating system tasks, such as opening a file. When the WebAssembly VM encounters those function names at runtime, it automatically calls the corresponding operating system standard library function to perform the task and return the result.

In order for WASI to work, we need a compiler toolchain to compile Rust (or other languages) standard library functions, such as opening a file, into bytecode that makes the corresponding WASI calls. The [`ssvmup`](https://github.com/second-state/ssvmup) tool uses the `wasm32-wasi` compiler backend for Rust. It supports WASI out of the box.

{% hint style="success" %}
The example source code for this tutorial is [here](https://github.com/second-state/wasm-learning/tree/master/nodejs/wasi).
{% endhint %}

### Get random number

The WebAssembly VM is a pure software construct. It does not have a hardware entropy source for random numbers. That's why WASI defines a function for WebAssembly programs to call its host operating system to get a random seed. As a Rust developer, all you need is to use the popular (de facto standard) `rand` and `getrandom` crates. Those crates are written in a way that instructs the `wasm32-wasi` compiler backend to generate the correct WASI calls in the WebAssembly bytecode. The `Cargo.toml` dependencies are as follows.

```
[dependencies]
rand = "0.7.3"
getrandom = "0.1.14"
wasm-bindgen = "=0.2.61"
```

The Rust code to get random number from WebAssembly is this.

```
use wasm_bindgen::prelude::*;
use rand::prelude::*;

#[wasm_bindgen]
pub fn get_random_i32() -> i32 {
  let x: i32 = random();
  return x;
}

#[wasm_bindgen]
pub fn get_random_bytes() -> Vec<u8> {
  let mut vec: Vec<u8> = vec![0; 128];
  getrandom::getrandom(&mut vec).unwrap();
  return vec;
}
```

The Javascript code to call the Rust functions from Node.js is as follows.

```
const { get_random_i32, get_random_bytes } = require('../pkg/wasi_example_lib.js');

console.log( "My random number is: ", get_random_i32() );
console.log( "My random bytes are");
console.hex( get_random_bytes() );
```

Now, let's run this example in SSVM in Node.js.

```
$ ssvmup build
$ node node/app.js
... ...
```

More to come later for WASI functions to access the file system, console / stdout, time / clock, and network requests.

### Printing and debugging from Rust

The Rust `println!` marco just works in WASI. The statements print to the `STDOUT` of the process that runs the SSVM. In Node.js apps, it is the `STDOUT` on the Node.js server.


# The storage interface

Access high performance storage and databases from a Rust API

## This page is outdated. Please visit here to check out how to [access storage interface Rust APIs](https://www.secondstate.io/articles/the-storage-interface-in-ssvm/).

The [SSVM storage interface](https://github.com/second-state/specs/blob/master/storage_interface.md) provides a Rust API that allows programs to persist arbitrary  data into a key value store. The data store is configured and started by the SSVM and hence is transparent to the Rust application. Rust developers can view this as an abstract storage space for application data.&#x20;

{% hint style="info" %}
The storage interface provides much higher performance and data throughput than using WASI calls to access database on the file system or via network. It is also much easier to work with than most database APIs in Rust.
{% endhint %}

{% hint style="success" %}
The example source code for this tutorial is [here](https://github.com/second-state/wasm-learning/tree/master/nodejs/storage).
{% endhint %}

### Dependency

You will need to include the [rust\_storage\_interface\_library](https://crates.io/crates/rust_storage_interface_library) crate in your `Cargo.toml`. In many cases, you will also need [serde](https://serde.rs/) dependency for storing and loading structs. Add dependency for [serialize\_deserialize\_u8\_i32](https://crates.io/crates/serialize_deserialize_u8_i32) if you wish to store `Vec<u8>` or `&[u8]` byte arrays.

```
[dependencies]
rust_storage_interface_library = "^0.1"
serialize_deserialize_u8_i32 = "^0.1"
serde = { version = "^1.0", features = ["derive"] }
serde_json = "1.0"
wasm-bindgen = "=0.2.61"
```

In your Rust code, do this.

```
use serialize_deserialize_u8_i32::s_d_u8_i32;
use rust_storage_interface_library::ssvm_storage;
```

### Store and load primitive types

With a simple API call, you can store and load Rust data of primitive types.

```
// store boolean
let boolean1: bool = true;
let storage_key: i32 = ssvm_storage::store::store(boolean1);
// load boolean
let boolean2: bool = ssvm_storage::load::load_as_bool(storage_key);

// store char
let char1: char = 'a';
let storage_key: i32 = ssvm_storage::store::store(char1);
// load char
let char2: char = ssvm_storage::load::load_as_char(storage_key);

// store i64
let i641: i64 = 1234567890;
let storage_key: i64 = ssvm_storage::store::store(i641);
// load i64
let i642: i64 = ssvm_storage::load::load_as_i64(storage_key);

// store f64
let f641: f64 = 3.1415926536;
let storage_key: i64 = ssvm_storage::store::store(f641);
// load i64
let f642: f64 = ssvm_storage::load::load_as_f64(storage_key);
```

### Store and load string data

Strings are similarly easy. With string capabilities, you can store and load complex JSON structures.

```
// store a string
let my_string = String::from("A string to store");
let storage_key: i32 = ssvm_storage::store::store(my_string);
// load a string
let my_loaded_string = ssvm_storage::load::load_as_string(storage_key);
```

### Store and load structs data

With serde, it is easy to store a struct. Notice that, when you load the data, you will need to pass in an "empty" struct of the same type in order for the the compiler to know the returned struct type.

```
// Define the struct
#[derive(Serialize, Deserialize, PartialEq, Debug, Default)]
struct TestStruct {
    a_vec: Vec<u8>,
    a_i32: i32,
    a_u8: u8,
    a_bool: bool,
}

// Store the struct
let test_struct1 = TestStruct {
    a_vec: vec![134, 122, 131],
    a_i32: 4,
    a_u8: 4,
    a_bool: true,
};
let storage_key: i32 = ssvm_storage::store::store(test_struct1);

// Load the struct
// Instantiate the struct, just using the default (no actual data necessary, this is just a placeholder to pass in so the call will return your data as the correct type)
let struct_skeleton = TestStruct::default();
let my_loaded_struct: TestStruct = ssvm_storage::load::load_as_struct(struct_skeleton, storage_key);
```

### Store and load binary data

Often times, it is easier just to store data in binary format as a byte array. Think file content, images, videos, and binary serialized structs etc. With the storage interface, we do that by packing and unpacking the byte array into `i32` arrays.

```
// Store byte array Vec<u8>
let bytes : Vec<u8> = vec![134, 122, 131, 111];
let bytes_in_i32: Vec<i32> = s_d_u8_i32::serialize_u8_to_i32(bytes);
let storage_key: i32 = ssvm_storage::store::store_as_i32_vector(bytes_in_i32);

// Load Vec<u8>
let bytes_in_i32_1: Vec<i32> = ssvm_storage::load::load_as_i32_vector(storage_key);
let mut bytes_1: Vec<u8> = s_d_u8_i32::deserialize_i32_to_u8(bytes_in_i32_1);
```

For more examples and how it works under the hood, please review the [spec document](https://github.com/second-state/specs/blob/master/storage_interface.md).


# The inference interface

Use AI hardware to accelerate inference operations in WebAssembly

## This page is outdated. Please[ visit here for the most up-to-date content](https://www.secondstate.io/tags/rust-function-in-nodejs/).

One of the key benefits of Rust is that it is close to the hardware and can fully take advantage of new hardware features. That is most interesting in the area of Artificial Intelligence (AI), where almost all major cloud players now have their own customized silicon chips for AI inference.

![](/files/-M7kjihQaHCgq57dtWm1)

The SSVM inference interface enables Rust applications to directly drive natively compiled ONNX and Tensorflow models on those new hardware. We do that through Rust and WebAssembly code instead of C++ native code for better safety, portability, and manageability.


# Examples and use cases

High performance, safe, portable, and manageable server-side apps using Rust

## This page is outdated. Please [visit here for the most up-to-date content](https://www.secondstate.io/tags/use-case/).

In this series of tutorials, we will demonstrate how to write and deploy Rust functions to perform encryption, machine learning, and artificial intelligence tasks in Node.js applications.

{% content-ref url="/pages/-M5cTEcxiDhBvbl5zYZX" %}
[Encryption and decryption](/server-side-webassembly/examples-and-use-cases/encryption-and-decryption)
{% endcontent-ref %}

{% content-ref url="/pages/-M5cTSFiw0l5qKnk2AuA" %}
[Machine learning](/server-side-webassembly/examples-and-use-cases/machine-learning)
{% endcontent-ref %}

{% content-ref url="/pages/-M5cTavdo4pFZGoXu5l2" %}
[Artificial intelligence](/server-side-webassembly/examples-and-use-cases/artificial-intelligence)
{% endcontent-ref %}


# Encryption and decryption

Use RSA public key algorithms to encrypt and decrypt

## This page is outdated. Please visit here to see the use case of [Rust function in encryption and decryption](https://www.secondstate.io/articles/encryption-and-decryption/).

One of the frequently performed computing tasks is public key encryption and decryption. Rust and C++ code vastly outperforms JavaScript code in these tasks. In this tutorial, let's use [pure Rust implementation of the RSA algorithm](https://crates.io/crates/rsa) as an example to show how to perform public key encryption and decryption in a Node.js web service.

{% hint style="success" %}
The example project source code is [here](https://github.com/second-state/rust-wasm-ai-demo).
{% endhint %}

The following Rust functions perform the encryption and decryption tasks.

* The `generate_key_pair()` function creates a random public / private key pair of specified length. The generated `RSAKeyPair` is serialized into a JSON string and returned to the JavaScript caller.
* The `encrypt()` function takes a `RSAPublicKey` in serialized JSON format, and a byte array message. It encrypts the message and returns the result as a byte array.
* The `decrypt()` function takes a `RSAPrivateKey` in serialized JSON format, and an encrypted byte array message. It decrypts the message and returns the result as a byte array.

```
use wasm_bindgen::prelude::*;
use rsa::{PublicKey, RSAPublicKey, RSAPrivateKey, PaddingScheme};
use rand::rngs::OsRng;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct RSAKeyPair {
  rsa_private_key: RSAPrivateKey,
  rsa_public_key: RSAPublicKey
}


#[wasm_bindgen]
pub fn generate_key_pair (bits: i32) -> String {
  let mut rng = OsRng;
  let private_key = RSAPrivateKey::new(&mut rng, bits as usize).expect("failed to generate a key");
  let public_key = private_key.to_public_key();
  let key_pair = RSAKeyPair {rsa_private_key: private_key, rsa_public_key: public_key};
  return serde_json::to_string(&key_pair).unwrap();
}

#[wasm_bindgen]
pub fn decrypt (pk: &str, data: &[u8]) -> Vec<u8> {
  let private_key: RSAPrivateKey = serde_json::from_str(pk).unwrap();
  return private_key.decrypt(PaddingScheme::PKCS1v15, data).expect("failed to decrypt");
}

#[wasm_bindgen]
pub fn encrypt (pk: &str, data: &[u8]) -> Vec<u8> {
  let mut rng = OsRng;
  let public_key: RSAPublicKey = serde_json::from_str(pk).unwrap();
  return public_key.encrypt(&mut rng, PaddingScheme::PKCS1v15, data).expect("failed to encrypt");
}
```

The Javascript host application calls the Rust functions as follows. It first calls the Rust `generate_key_pair()` function to generate the key pair, and then saves the generated public and private keys respectively. It then uses the public key to encrypt a string message, and then use the private key to decrypt that message. The keys are serialized into JSON strings before passing to the Rust functions.

```
const { generate_key_pair, encrypt, decrypt } = require('../pkg/rsa_example_lib.js');

var kp = JSON.parse(generate_key_pair(2048));
var public_key = kp['rsa_public_key'];
var private_key = kp['rsa_private_key'];

var msg = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
var enc_data = encrypt(JSON.stringify(public_key), encoder.encode(msg));
var dec_data = decrypt(JSON.stringify(private_key), enc_data);
console.log(decoder.decode(dec_data));
```

The RSA example is simple but provides substantial performance benefits when you run many public key encryption and decryption operations.

For a more complex example of public key encryption and decryption, please see our [Recrypt-as-a-Service](https://github.com/second-state/recrypt-as-a-service) repo. It is a scalable approach for individuals to control access to private data without shared secrets or storing secrets (e.g., private keys) on a centralized service. As a part of the workflow, the web service needs to perform large amounts of proxy encryption using public keys. Rust and WebAssembly are ideally suited for this.


# Machine learning

Use k-means clustering algorithm to classify data points

## This page is outdated. Please visit here to see the use case of[ Rust function in machine learning](https://www.secondstate.io/articles/machine-learning/).

The lingua franca of machine learning is Python. However, Python relies on C/C++ based native modules to perform the actual computationally intensive tasks of machine learning. It is similar to Node.js relying on C++ to perform computing tasks.

For new machine learning algorithms, developers can choose to implement them in Python for developer productivity or in C++ for runtime efficiency. Now, there is a third choice. Implementing machine learning algorithms in Rust could provide a 25x performance gain over Python as well as safety over C++. In this tutorial, we will demonstrate how to do k-means clustering computation in Rust, and make the function available in Node.js.

{% hint style="success" %}
The example source code for this tutorial is [here](https://github.com/second-state/wasm-learning/tree/master/nodejs/kmeans).
{% endhint %}

The Rust function `fit()` is as follows. It reads content from a CSV data file, and group the points into clusters based on the dimensions for the points and the number of estimated clusters.

```
use wasm_bindgen::prelude::*;
use ndarray::{Array2};
use std::str::FromStr;

#[wasm_bindgen]
pub fn fit (csv_content: &[u8], dim: i32, num_clusters: i32) -> String {
    let data = read_data(csv_content, dim as usize);
    let (means, _clusters) = rkm::kmeans_lloyd(&data.view(), num_clusters as usize);
    return serde_json::to_string(&means).unwrap();
}

fn read_data(csv_content: &[u8], dim: usize) -> Array2<f32> {
    let mut data_reader = csv::Reader::from_reader(csv_content);
    let mut data: Vec<f32> = Vec::new();
    for record in data_reader.records() {
        for field in record.unwrap().iter() {
            let value = f32::from_str(field);
            data.push(value.unwrap());
        }
    }
    Array2::from_shape_vec((data.len() / dim, dim), data).unwrap()
}
```

The Javascript host application reads the CSV file, and calls the Rust function to perform the computation. The results are returned as a multi-dimensional array for the cluster centers.

```
const { fit } = require('../pkg/kmeans_lib.js');
const fs = require('fs'); 

var birch3_csv = fs.readFileSync("birch3.data.csv");
var means = JSON.parse( fit(birch3_csv, 2, 100) );
console.log(means);
```

Rust and WebAssembly made it easy to make high performance machine learning algorithms available as web services.


# Artificial intelligence

Image recognition using Tensorflow

## This page is outdated. Please Please visit here to see the use case of [Rust function in AI](https://www.secondstate.io/articles/artificial-intelligence/).

This example shows how to write a Rust function for image recognition, and then offer this function as AI-as-a-Service.

{% embed url="<https://www.youtube.com/watch?v=Ce2am-ugQhg>" %}

Using machine learning libraries in Rust, such as the [Tract](https://github.com/snipsco/tract) crate which supports both Tensorflow and ONNX inference model, we can write AI-as-a-Service functions in Node.js. The functions could take AI models and input data, and return inference results, such as recognized objects on an input image, through a web service.

{% hint style="success" %}
The example project source code is [here](https://github.com/second-state/rust-wasm-ai-demo).
{% endhint %}

The following Rust function does the inference.

* The `infer()` function takes raw bytes for an already-trained Tensorflow model from ImageNet, and an input image.
* The `infer_impl()` function resizes the image, applies the model to it, and returns the top matched label and probability. The label indicates an object the ImageNet model has been trained to recognize.

```
use wasm_bindgen::prelude::*;
use tract_tensorflow::prelude::*;
use std::io::Cursor;

#[wasm_bindgen]
pub fn infer(model_data: &[u8], image_data: &[u8]) -> String {
    let res: (f32, u32) = infer_impl (model_data, image_data, 224, 224).unwrap();
    return serde_json::to_string(&res).unwrap();
}

fn infer_impl (model_data: &[u8], image_data: &[u8], image_height: usize, image_width: usize) -> TractResult<(f32, u32)> {
    // load the model
    let mut model_data_mut = Cursor::new(model_data);
    let mut model = tract_tensorflow::tensorflow().model_for_read(&mut model_data_mut)?;
    model.set_input_fact(0, InferenceFact::dt_shape(f32::datum_type(), tvec!(1, image_height, image_width, 3)))?;
    // optimize the model and get an execution plan
    let model = model.into_optimized()?;
    let plan = SimplePlan::new(&model)?;
    
    // open image, resize it and make a Tensor out of it
    let image = image::load_from_memory(image_data).unwrap().to_rgb();
    let resized = image::imageops::resize(&image, image_height as u32, image_width as u32, ::image::imageops::FilterType::Triangle);
    let image: Tensor = tract_ndarray::Array4::from_shape_fn((1, image_height, image_width, 3), |(_, y, x, c)| {
        resized[(x as _, y as _)][c] as f32 / 255.0
    })
    .into();
    
    // run the plan on the input
    let result = plan.run(tvec!(image))?;
    
    // find and display the max value with its index
    let best = result[0]
        .to_array_view::<f32>()?
        .iter()
        .cloned()
        .zip(1..)
        .max_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
    match best {
        Some(t) => Ok(t),
        None => Ok((0.0, 0)),
    }
}
```

The Javascript function reads the model and image files, and calls the Rust function.

```
const { infer } = require('../pkg/csdn_ai_demo_lib.js');

const fs = require('fs');
var data_model = fs.readFileSync("mobilenet_v2_1.4_224_frozen.pb");
var data_img_cat = fs.readFileSync("cat.png");
var data_img_hopper = fs.readFileSync("grace_hopper.jpg");

var result = JSON.parse( infer(data_model, data_img_hopper) );
console.log("Detected object id " + result[1] + " with probability " + result[0]);

var result = JSON.parse( infer(data_model, data_img_cat) );
console.log("Detected object id " + result[1] + " with probability " + result[0]);
```

Next, build it with `ssvmup`, and then run the Javascript file in Node.js.

```
$ ssvmup build
$ cd node
$ node app.js
Detected object id 654 with probability 0.3256046
Detected object id 284 with probability 0.27039126
```

You can look up the output detected object ID from the [imagenet\_slim\_labels.txt](https://github.com/second-state/rust-wasm-ai-demo/blob/master/node/imagenet_slim_labels.txt) file from ImageNet.

```
... ...
284 tiger cat
... ...
654 military uniform
... ...
```

Now, it should be easy for you to turn this example into a Node.js-based web service so that users can send in images and detect objects!


# SSVM Performance

Performance benchmark for the SSVM against other WebAssembly runtimes

## This page is outdated. Please [visit here for the most up-to-date content](https://www.secondstate.io/articles/ssvm-performance/).

The Second State Virtual Machine ([SSVM](https://github.com/second-state/ssvm))  is an open source WebAssembly runtime optimized for server-side applications. The SSVM provides not only a WebAssembly runtime in Node.js, but also a compiler toolchain [ssvmup](https://github.com/second-state/ssvmup) for Rust and JavaScript.

#### Performance benchmarks

{% hint style="info" %}
The benchmark scores are in seconds. The smaller the better. The 👍emoji marks the two best performing runtimes for each benchmark. The docker+native runtime is a simple Ubuntu Docker on an Ubuntu host.
{% endhint %}

|                     | [SSVM](https://github.com/second-state/SSVM)❤️ | [Lucet](https://github.com/bytecodealliance/lucet) / [wasmtime](https://github.com/bytecodealliance/wasmtime) | [WAVM](https://github.com/WAVM/WAVM) | [V8](https://github.com/v8/v8) | docker+native |
| ------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------ | ------------------------------ | ------------- |
| nop 0               | 0.003👍                                        | 0.002👍                                                                                                       | 0.024                                | 0.056                          | 0.849         |
| cat-sync 0          | 0.007👍                                        | 0.573                                                                                                         | 0.029👍                              | 0.06                           | 0.826         |
| nbody-c 50M         | 3.716👍                                        | 4.611                                                                                                         | 3.753                                | 3.408👍                        | 4.128         |
| nbody-cpp 50M       | 3.759👍                                        | 4.705                                                                                                         | 3.741👍                              | 3.962                          | 3.944         |
| fannkuch-redux-c 12 | 28.06👍                                        | 53.104                                                                                                        | 28.477                               | 29.285                         | 24.459👍      |
| mandelbrot-c 15K    | 10.347👍                                       | 28.97                                                                                                         | 12.072👍                             | 18.062                         | 16.05         |
| binary-trees-c 18   | 1.328👍                                        | 2.91                                                                                                          | 1.612👍                              | 2.002                          | 17.191        |


# Getting started

Write and deploy Rust functions as web services

## This page is outdated. Please [visit here for the most up-to-date content](https://www.secondstate.io/articles/why-webassembly-server/).

The Second State FaaS service (currently in public beta) enables you to write Rust functions, and make them available as RESTful web services. Key features:

* Each Rust function is a RESTful endpoint
* Input arguments can be supplied via the HTTP request or from another URL
* Return values can be in the HTTP response body or redirected to another URL
* Stateful execution
* Finely-grained resource metering (based on Opscode)
* Much faster and lighter compared with Docker
* No-wait code start
* Access to native OS and system features
* Access to customized hardware (e.g., AI inference chips)
* Works across multiple clouds

## **Setup**

First, let's install Rust and Node.js on the dev computer. Node.js is needed for our toolchain. If you have already done it, you can skip these steps.

```
# Prerequisite
$ sudo apt-get update
$ sudo apt install -y build-essential curl wget git vim libboost-all-dev

# Install rust
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ source $HOME/.cargo/env

# Install nvm
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
# Follow the on-screen instructions to logout and then log in

# Install node
$ nvm install v10.19.0
$ nvm use v10.19.0
```

The `ssvmup` npm module installs the Second State Virtual Machine (SSVM) into Node.js as a native `addon`, and provides the necessary compiler tools. Follow the steps below to install Rust and the `ssvmup` tool.

```
# Install ssvmup toolchain
$ npm install -g ssvmup # Append --unsafe-perm if permission denied

# Install the nodejs addon for SSVM
$ npm install ssvm
```

## **WebAssembly program in Rust**

In this example, our Rust program appends the input string after “hello”. Let’s create a new `cargo` project. Since this program is intended to be called from a host application, not to run as a stand-alone executable, we will create a `hello` project.

```
$ cargo new --lib hello
$ cd hello
```

Edit the `Cargo.toml` file to add a `[lib]` section. It tells the compiler where to find the source code for the library and how to generate the bytecode output. We also need to add a dependency of `wasm-bindgen` here. It is the utility `ssvmup` uses to generate the JavaScript binding for the Rust WebAssembly program, which is required by the FaaS runtime.

```
[lib]
name = "hello_lib"
path = "src/lib.rs"
crate-type =["cdylib"]

[dependencies]
wasm-bindgen = "=0.2.61"
```

Below is the content of the Rust program `src/lib.rs`. You can see that it takes two input parameters. Let's not worry about the `context` at this moment. The function parameter `s` comes from the HTTP request when a user calls this function over the web.

```
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn say(context: &str, s: &str) -> String {
  let r = String::from("hello ");
  return r + &s;
}
```

Next, you can compile the Rust source code into WebAssembly bytecode.

```
$ ssvmup build --nowasi
```

The result are files in the `pkg/` directory. the `.wasm` file is the WebAssembly bytecode program.

## Upload the wasm file to FaaS

Use the following `curl` command to upload the `wasm` file to the FaaS service. In the beta stage, it is all FREE!

```
$ curl --location --request POST 'https://rpc.ssvm.secondstate.io:8081/api/executables' \
--header 'Content-Type: application/octet-stream' \
--header 'SSVM_Description: say hello' \
--data-binary 'pkg/hello_lib_bg.wasm'
```

It returns an ID for the `wasm` file in the FaaS system.

```
{"wasm_id":123}
```

## Run the function

Use the following `curl` command to run the `say()` function in the wasm program. The argument `s` for this function call is passed in as a string in the HTTP request body.

```
$ curl --location --request POST 'https://rpc.ssvm.secondstate.io:8081/api/run/123/say' \
--header 'Content-Type: text/plain' \
--data-raw 'Second State FaaS'
```

The HTTP response body is as follows.

```
hello Second State FaaS
```

## What's next

In the next article, we will learn how to give the Rust function a persistence context to customize its runtime behavior. That is where the first function parameter `context` comes into play.


# Context

Give the function a context

## This page is outdated. Please [visit here for the most up-to-date content](https://www.secondstate.io/articles/why-webassembly-server/).

The first argument of any function must be a `&str`. You can use it to pass a `context` value to every function call. For example, we can set a `context` string for wasm ID `123`, which is the hello world wasm example we just created. The context specifies that the function should say hello in emoji.

```
curl --location --request PUT 'https://rpc.ssvm.secondstate.io:8081/api/state/123' \
--header 'Content-Type: text/plain' \
--data-raw 'emoji'
```

The Rust function now looks like this.

```
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn say(context: &str, s: &str) -> String {
  if context == "emoji" {
    let r = String::from("👋 ");
    return r + &s;
  } else {
    let r = String::from("hello ");
    return r + &s;
  }
}
```

The next time you run it, it says hello based on the context.

```
$ curl --location --request POST 'https://rpc.ssvm.secondstate.io:8081/api/run/123/say' \
--header 'Content-Type: text/plain' \
--data-raw 'Second State FaaS'
```

The response is as follows.

```
👋 Second State FaaS
```

We have just used a simple string as the context. For more complex use cases, the context could be a JSON object. You can set the state to the entire JSON string. The function is responsible for parsing the JSON string argument and makes sense of it.

You can also store the Second State VM storage ID in the stateful context. That enables stateful functions that can update and maintain its internal states across execution runs.  We will cover that use case in a later tutorial.


# Send result to another service

Chain multiple functions together

## This page is outdated. Please [visit here for the most up-to-date content](https://www.secondstate.io/articles/why-webassembly-server/).

A common use case of serverless functions is to act as the bridge between several web services or messaging queues. It receives a request from a source, and then send the return value onto the next service.

The way to accomplish that is to return a JSON string from the function. If the JSON object contains a `callback` object, the FaaS would strip it from the return value, and then send the rest of the return value to the HTTP endpoint defined in the callback.

In the following example, the `say()` function returns a JSON `callback`, which requests SendGrid to send the hello messages as an email. The Rust function is as follows.

```
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn say(context: &str, s: &str) -> String {
  let r = String::from("hello ");
  let ret = "
    {
      'callback': {
        'method': 'POST',
        'hostname': 'api.sendgrid.com',
        'port': 443,
        'path': '/v3/mail/send',
        'headers': {
          'Content-Type': 'application/json',
          'authorization': 'Bearer AUTH_TOKEN'
        },
        'maxRedirects': 20
      },
      'personalizations': {
        [{
          'to':[{'email':'TO_EMAIL','name':''}],
          'subject':'SUBJECT'
        }],
        'from':{'email':'FROM_EMAIL','name':''}
      }
    }
  ";
  
  let ret = ret.replace("AUTH_TOKEN", "auth_token_123");
  let ret = ret.replace("TO_EMAIL", "alice@secondstate.io");
  let ret = ret.replace("SUBJECT", &(r + &s));
  let ret = ret.replace("FROM_EMAIL", "dev@developer.com");
  return ret;
}
```

The `callback` object in the return value is as follows. It conforms to the Node.js request options specification.

```
{
  'method': 'POST',
  'hostname': 'api.sendgrid.com',
  'port': 443,
  'path': '/v3/mail/send',
  'headers': {
    'Content-Type': 'application/json',
    'authorization': 'Bearer <<YOUR_API_KEY>>'
  },
  'maxRedirects': 20
}
```

The HTTP body sent to SendGrid is as follows.

```
{'personalizations':
  [{
    'to':[{'email':"dev@example.com","name":""}],
    'subject':'hello email'
  }],
  'from':{'email':'alice@secondstate.io','name':''}
}
```

The recipient email address and auth token are currently hardcoded in the Rust source code. But you can use the stateful context in the previous article to configure them! Just set a JSON configuration object in the state. Try it!

You can see that the `callback` could direct the result from one function to another, and hence chaining multiple functions together.


# Input and output

The FaaS function can take a variety of different input and output options

TBD


# JSON argument

Use JSON strings as function arguments

## This page is outdated. Please [visit here for the most up-to-date content](https://www.secondstate.io/articles/why-webassembly-server/).

## Strongly typed data structures

Rust is able to map a JSON string to a Rust object using what is known as a [strongly typed data structure](https://docs.serde.rs/serde_json/#parsing-json-as-strongly-typed-data-structures). The following Rust code defines the `Person` data before compile time.

```rust
struct Person {
    name: String,
    age: u8,
    phones: Vec<String>,
}
```

The Rust code can create a `Person` object, in a strongly typed fashion, using the following syntax.

```rust
let p: Person = serde_json::from_str(data)?;
```

In the case above, the JSON string used to create the object would be as follows.

```rust
{
    "name": "John Doe",
    "age": 43,
    "phones": [
        "+44 1234567",
        "+44 2345678"
    ]
}
```

This strongly typed approach may be perfect if the data is defined up front and not likely to change. This strongly typed approach is also perfectly suitable for simple flat data (which is not nested).

If the JSON string being presented to the Rust application is likely to have extra or missing fields (in some situations) or is complex in nature (contains several nested layers) then please consider mapping the JSON string to a Rust object using an untyped data structure.

## Untyped data structures

Instead of writing complex nested Structs before compile time, you could use [serde\_json's generic Value type](https://docs.serde.rs/serde_json/value/enum.Value.html) as demonstrated in the following code. This approach allows for maximum flexiblility.

```rust
use serde_json;
use serde_json::{Value};

#[no_mangle]
fn process(s: &str){
    let json_as_object: Value = serde_json::from_str(s).unwrap();
}
```

The above approach allows the string to be parsed, regardless of its structural complexity. Once parsed, you can simply access each of the keys and values using syntax like the following.

```rust
json_as_object["outer_object"]["middle_nested"]["inner_nested"]["value_to_use_in_app"]
```

## SSVM\_Callback argument

It is possible for a function to initiate further processing via the use of a callback. This functionality is optional, but very useful and worth learning about.

**Important notes:**

* Please ensure that the data for the callback object adheres to the standard shown below (1)
* Please ensure that the data for the callback object is wrapped in a single `SSVM_Callback` wrapper as shown below (2)
* Please ensure that the `SSVM_Callback` object is at the top level as shown below (3)

(1) Before we begin with an example, please note that it is important to adhere to the following request structure when creating your own callback object in your Rust / Wasm code.

```javascript
{
    "method": "POST",
    "hostname": "rpc.ssvm.secondstate.io",
    "port": 8081,
    "path": "/api/run/1/my_function",
    "headers": {
      "Content-Type": "application/json"
    },
    "maxRedirects": 20
}
```

This is the standard request format which Javascript/Nodejs uses. It will be passed straight into a request programatically and therefore the structure and the key:value entries must conform to the standard [outlined here](https://nodejs.org/api/https.html#https_https_request_options_callback).

(2) Please note that over and above the example we have just used ... there **must be an additional `SSVM_Callback` object which wraps the standard request format**. Here is the complete example of what your callback argument should look like; note the `{"SSVM_Callback": {}}` wrapper.

```javascript
{
    "SSVM_Callback": {
        "method": "POST",
        "hostname": "rpc.ssvm.secondstate.io",
        "port": 8081,
        "path": "/api/run/1/my_function",
        "headers": {
            "Content-Type": "application/json"
        },
        "maxRedirects": 20
    }
}
```

(3) Please note that the `SSVM_Callback` is a standalone object which is always at the top level (along side other top level objects as required)

```javascript
{
    "function": {
        "name": "new template name"
    },
    "SSVM_Callback": {
        "method": "POST",
        "hostname": "rpc.ssvm.secondstate.io",
        "port": 8081,
        "path": "/api/run/1/my_function",
        "headers": {
            "Content-Type": "application/json"
        },
        "maxRedirects": 20
    }
}
```

### Callback example

In some cases the results of a specific function's output may be used for another function's input. This function as a service infrastructure allows a callback\_url argument to be passed into a function, along with the function's other arguments.

Below is an example of a single HTTP POST request which can perform two different tasks by calling a second endpoint, using the data derived from the calculations at the first endpoint. Specifically, we find the average of two temperatures, and then send that result off for conversion from Celsius to Fahrenheit.

Consider the following Rust / Wasm code (`my_first_function`)

```rust
use serde_json;
use serde_json::json;
use serde_json::Value;

#[no_mangle]
fn my_first_function(_function_data: &str) -> String {
    let function_data_as_object: Value = serde_json::from_str(_function_data).unwrap();
    let answer: f64 = (function_data_as_object["first_function_input"]["left_temperature"]
        .as_f64()
        .unwrap()
        + function_data_as_object["first_function_input"]["right_temperature"]
            .as_f64()
            .unwrap())
        / 2.0;
    let response = json!({
    "first_function_output": {"average_temperature_as_celsius": answer}
    });
    response.to_owned().to_string()
}
```

The above `my_first_function` can be called using the following JSON string input (notice the `SSVM_Callback` to `my_other_function` at `wasm_id` `2` that is being passed in as input)

```javascript
{
    "SSVM_Callback": {
        "method": "POST",
        "hostname": "rpc.ssvm.secondstate.io",
        "port": 8081,
        "path": "/api/run/2/my_other_function",
        "headers": {
            "Content-Type": "application/json"
        },
        "maxRedirects": 20
    },
    "first_function_input": {
        "left_temperature": 35,
        "right_temperature": 38
    }
}
```

The following is an example of the inputs and outputs that are derived as the entire request/response process unfolds.

A caller now issues the following HTTP request to `my_first_function` (the wasm executable at `wasm_id` `1`)

```bash
curl --location --request POST 'https://rpc.ssvm.secondstate.io:8081/api/run/1/my_first_function' \
--header 'Content-Type: application/json' \
--data-raw '{
    "SSVM_Callback": {
        "method": "POST",
        "hostname": "rpc.ssvm.secondstate.io",
        "port": 8081,
        "path": "/api/run/2/my_other_function",
        "headers": {
            "Content-Type": "application/json"
        },
        "maxRedirects": 20
    },
    "first_function_input": {
        "left_temperature": 35,
        "right_temperature": 38
    }
}'
```

As we can see in the Rust source code above, `my_first_function` finds the `average_temperature_as_celsius` (given the `left_temperature` and the `right_temperature` of the `first_function_input`). The result of the execution of `my_first_function` looks like this.

```javascript
{
    "first_function_output": {
        "average_temperature_as_celsius": 36.5
    }
}
```

You may be wondering why we passed the `SSVM_Callback` into `my_first_function` as an input?

The reason for this is because it is not wise to hard code a callback (into your source code) because most of the time the callback's data would have some private credentials in it i.e. an API key or a password etc. It is safer to only pass the callback to `rpc.ssvm.secondstate.io` via HTTPS and let the callback execute securely inside the `POST` request.

Here is the latter part of the execution (the callback). Consider the following function `my_other_function` at `wasm_id` `2` which converts the `average_temperature_as_celsius` to fahrenheit.

```rust
#[no_mangle]
fn my_other_function(_function_data:  &str) -> String {
    let function_data_as_object: Value = serde_json::from_str(_function_data).unwrap();
    let new_answer = function_data_as_object["first_function_output"]["average_temperature_as_celsius"].as_f64().unwrap() * (9.0/5.0) + 32.0;
    let response = json!({
    "other_function_output": {"average_temperature_as_fahrenheit": new_answer}
    });
    response.to_owned().to_string()
}
```

We have demonstrated here that each Wasm executable does return data, these multihop function executions (which use the callback object as input to the first callable function) facilitate all of the work to be handled internally. For example, if the caller issued the following HTTP POST request, they would simply get back one response which shows the `average_temperature_as_fahrenheit`. All of the other inner workings are not visible to the caller.

```
curl --location --request POST 'https://rpc.ssvm.secondstate.io:8081/api/run/1/my_first_function' \
--header 'Content-Type: application/json' \
--data-raw '{
    "SSVM_Callback": {
        "method": "POST",
        "hostname": "rpc.ssvm.secondstate.io",
        "port": 8081,
        "path": "/api/run/2/my_other_function",
        "headers": {
            "Content-Type": "application/json"
        },
        "maxRedirects": 20
    },
    "first_function_input": {
        "left_temperature": 35,
        "right_temperature": 38
    }
}'
```

The above request, produces the following result.

```javascript
{"other_function_output":{"average_temperature_as_fahrenheit":97.7}}
```


# Binary argument

Use a byte array as function call argument

TBD


# Multiple arguments

Use multipart HTTP request for function call

TBD


# Argument from a URL

Get a function call argument from an URL

TBD


# JSON return value

Return a JSON value from the function

TBD


# Binary return value

Return binary data from the function call

TBD


# Redirect return value

Redirect the JSON return value to another HTTP service endpoint

TBD


# Stateful execution

Make the function stateful

TBD


# Deno, Rust and WebAssembly

How to extend Deno with Rust and WebAssembly functions

## This page is outdated. Please visit here to [how to extend Deno with Rust and WebAssembly functions.](https://www.secondstate.io/articles/deno-rust-and-webassembly/)

[Deno](https://deno.land/) is a JavaScript / Typescript runtime written in Rust. It is based on Google V8 engine (same as Node.js) and created by [Ryan Dahl](https://en.wikipedia.org/wiki/Ryan_Dahl) -- the creator and original developer of Node.js.

**Q: Is Deno going to replace Node.js?**&#x20;

A: It could. If it does, it will be one of the coming-to-age events for the Rust language for server-side applications. The same way Twitter made the Ruby language a legitimate choice for web apps almost 15 years ago. &#x20;

**Q: One of the great selling point of Deno is that it is written in Rust. Can I use Rust to enhance and extend Deno for my apps?**&#x20;

A: Yes. You can.

👉 [Use WebAssembly to run Rust functions in Deno](https://dev.to/lampewebdev/writing-webassembly-in-rust-and-runing-it-in-deno-144j)

👉 [Use the Deno feat native extension](https://github.com/denoland/deno/pull/3372) (similar to Node.js NAPI)

**Q: Are server-side WebAssembly runtimes, such as the** [**Second State VM**](https://cloud.secondstate.io/server-side-webassembly/getting-started)**, going to be available for Deno?**

A: Yes, we are working on it!

**Q: Can you run Deno in a serverless environment?**

A: Yes.

* AWS Lambda: <https://github.com/hayd/deno-lambda/tree/master/example>
* Azure Function: <https://deno.land/x/azure_functions/>

**Q: Is there a Deno-based serverless environment to run high performance Rust functions as services?**

A: We are working on that!


# A Rusty hello world

Getting started with the Rust programming language - Rust is the best-supported language on WebAssembly today.

## This page is outdated. Please visit here to see [a Rusty hello world](https://www.secondstate.io/articles/a-rusty-hello-world/).

While WebAssembly supports many programming languages, Rust by far has the best tooling. Rust is voted the most beloved programming language by StackOverflow users for the past 4 years in a row. It is one of the fastest-growing programming languages.

Rust is versatile and performant like C, but much safer than C due to its compiler design. Like C, it has a bit of a learning curve. In this tutorial, I will get you started with the Rust programming language. From here, you can learn much more about the Rust language through online resources like [the book](https://doc.rust-lang.org/book/).

#### **Install Rust**

On a typical Linux system, run the following commands to install Rust compiler and the `cargo` tool for build management.

```
$ sudo apt-get update
$ sudo apt-get -y upgrade

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ source $HOME/.cargo/env
```

#### **Hello world**

{% hint style="success" %}
The source code of the tutorial is [here](https://github.com/second-state/wasm-learning/tree/master/rust/hello).
{% endhint %}

First, let’s create a new project using `cargo`.&#x20;

```
$ cargo new hello
     Created binary (application) `hello` package
$ cd hello
```

The `main()` function in the `src/main.rs` file is the entry point when we execute the Rust application. The `src/main.rs` file content is as follows. The code just prints a string “hello world” to the standard output.

```
fn main() {
  println!(“Hello, world!”);
}
```

Next, build the binary executable file for your machine.

```
$ cargo build --release
   Compiling hello v0.1.0 (/home/ubuntu/wasm-learning/rust/hello)
    Finished release [optimized] target(s) in 0.22s
```

You can now run your first Rust program and see “Hello World!” on the console.&#x20;

```
$ target/release/hello
Hello, world!
```

#### **Interactive greeting**

{% hint style="success" %}
The source code of the tutorial is [here](https://github.com/second-state/wasm-learning/tree/master/rust/cli).
{% endhint %}

Again, let’s create a new project using `cargo`.&#x20;

```
$ cargo new cli
     Created binary (application) `cli` package
$ cd cli
```

The content of the `src/main.rs` file is as follows. The `env::args()` holds the string values passed from the command line when we execute the program. Here you can also see that we first create a Rust string, and then append more string references to it. Why do we have to concatenate string references instead of string values? Well, that is how Rust makes programs safe. You can [read more here](https://doc.rust-lang.org/book/ch08-02-strings.html).

```
use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    println!("{}", String::from("Hello ") + &args[1]);
}
```

Next, build the binary executable file for your machine.

```
$ cargo build --release
```

You can run the program and pass in a command-line argument.&#x20;

```
$ target/release/cli Rust
Hello Rust
```

#### **What about WebAssembly?**

Now we have seen how to create build native executable programs from Rust source code. The executable program can only run on your build machine and could be unsafe. In the next tutorial, I will show you.&#x20;

* How to build WebAssembly bytecode programs instead of native executable files from Rust source code.
* How to interact with WebAssembly programs via a web browser instead of the cumbersome command line.

Stay tuned!


# Rust and WebAssembly

Run Rust programs in WebAssembly

## This page is outdated. Please visit here to see how to [run Rust  programs in WebAssembly](https://www.secondstate.io/articles/rust-and-webassembly/).&#x20;

In this tutorial, we will create a very simple but complete WebAssembly application. A WebAssembly application typically has two parts.

* The bytecode program that runs inside the WebAssembly virtual machine to perform computing tasks
* The host application that provides UI, networking, database, and calls the WebAssembly program to perform key computing tasks or business logic

In this tutorial, the host application is written in JavaScript and runs inside a web browser. The WebAssembly bytecode program is written in Rust. Now, let’s check out the Rust program.&#x20;

{% hint style="success" %}
The source code of the tutorial is [here](https://github.com/second-state/wasm-learning/tree/master/browser/triple).
{% endhint %}

#### **WebAssembly program in Rust**

In this example, our Rust program simply triples an input number and returns the result. Let’s first install WebAssembly tools to the Rust compiler.&#x20;

```
# Install Rust

$ sudo apt-get update
$ sudo apt-get -y upgrade
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ source $HOME/.cargo/env
```

```
# Install WebAssembly tools

$ rustup target add wasm32-unknown-unknown
$ rustup override set nightly
$ rustup target add wasm32-unknown-unknown --toolchain nightly
```

Next, create a new `cargo` project. Since this program is intended to be called from a host application, not to run as a stand-alone executable, we will create a `lib` project.

```
$ cargo new --lib triple
$ cd triple
```

Edit the `Cargo.toml` file to add a `[lib]` section. It tells the compiler where to find the source code for the library and how to generate the bytecode output.

```
[lib]
name = "triple_lib"
path = "src/lib.rs"
crate-type =["cdylib"]
```

Below is the content of the Rust program `src/lib.rs`. You can actually define multiple external functions in this library file, and all of them will be available to the host JaveScript app via WebAssembly.&#x20;

```
#[no_mangle]
pub extern fn triple(x: i32) -> i32 {
  return 3 * x;
}
```

Next, you can compile the Rust source code into WebAssembly bytecode using the command below.&#x20;

```
$ cargo +nightly build --target wasm32-unknown-unknown --release
```

The WebAssembly bytecode file is `target/wasm32-unknown-unknown/release/triple_lib.wasm`.

#### **The JavaScript host**

We use JavaScript to load the WebAssembly bytecode program and call its functions. Since most web browsers already support WebAssembly, this JavaScript can actually run as a web page. Without further ado, here is the relevant part of a JavaScript module to load, export, and call WebAssembly functions. The complete web page source file is [here](https://github.com/second-state/wasm-learning/blob/master/browser/triple/html/index.html).&#x20;

```
<script>
  if (!('WebAssembly' in window)) {
    alert('you need a browser with wasm support enabled :(');
  }
  (async () => {
      const response = await fetch('triple_lib.wasm');
      const buffer = await response.arrayBuffer();
      const module = await WebAssembly.compile(buffer);
      const instance = await WebAssembly.instantiate(module);
      const exports = instance.exports;
      const triple = exports.triple;
      
      var buttonOne = document.getElementById('buttonOne');
      buttonOne.value = 'Triple the number';
      buttonOne.addEventListener('click', function() {
        var input = $("#numberInput").val();
        alert(input + ' tripled equals ' + triple(input));
      }, false);
  })();
</script>
```

You can see that the JavaScript code loads the `triple_lib.wasm` file in the WebAssembly virtual machine, exports its external functions, and then calls the functions as needed.

Put this HTML file and the `triple_lib.wasm` file on a web server and you can now access the web page to triple any number you enter on the page.

#### **What about strings?**

Now, you have noticed that this example is not really a hello world. The WebAssembly function computes numbers but does not manipulate strings as a real hello world would do. Why is that? We will answer in the next tutorial and give a real hello world example.&#x20;


# WebAssembly in the browser

Create a simple WebAssembly app in Rust, and then call it from JavaScript!

## This page is outdated. Please visit here to see [how WebAssembly works in the browser](https://www.secondstate.io/articles/webassembly-in-the-browser/).

WebAssembly was [originally invented](https://medium.com/wasm/webassembly-on-the-server-side-c584f874b4a3) as a technology solution to speed up code execution inside web browsers. It does not provide a full replacement for JavaScript, but rather works side-by-side with JavaScript. The idea is that JavaScript functions could pass computationally intensive tasks to WebAssembly functions. In this tutorial, we will demonstrate how a simple WebAssembly in-browser application works.

{% hint style="success" %}
The source code of the tutorial is [here](https://github.com/second-state/wasm-learning/tree/master/browser/hello).
{% endhint %}

A WebAssembly application typically has two parts.

* The bytecode program that runs inside the WebAssembly virtual machine. This program is compiled from high level languages such as Rust, TypeScript, and Go. So far, Rust provides the most comprehensive tooling support for WebAssembly, and hence it is the most widely used language for WebAssembly modules.
* The host application that provides UI, networking, database, and calls the WebAssembly program to perform key computing tasks or business logic. In the web browser setting, the host is the browser itself.

In this tutorial, the host application is written in JavaScript and runs inside a web browser. The source code of the tutorial is [here](https://github.com/second-state/wasm-learning/blob/master/browser/triple.md). The WebAssembly bytecode program is written in Rust. Now, let’s check out the Rust program.&#x20;

![](/files/-M4plHnIrT5zMqo19e9W)

> The lightweight WebAssembly virtual machine only supports very limited numeric data types. The host application, on the other hand, probably needs to handle complex data types. One such complex data type is the string. The string is complicated because it contains data of unknown size and of unknown structure (i.e., encoding). The host application cannot directly pass string data to and from WebAssembly. It must convert string values to and from numeric values and arrays. You can [read more about it here](https://medium.com/wasm/strings-in-webassembly-wasm-57a05c1ea333).

#### **Setup**

The important development tool we introduce in this tutorial is the `wasm-pack`. It compiles Rust source code into a WebAssembly bytecode program, and then generates a JavaScript module that can interact with the WebAssembly program. The generated code takes care of input / output data encoding and management. This makes it much easier for JavaScript developer to call WebAssembly functions. Follow the steps below to install Rust and the `wasm-pack` tool.

```
# Install Rust

$ sudo apt-get update
$ sudo apt-get -y upgrade
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ source $HOME/.cargo/env
```

```
# Install wasm-pack tools

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

#### **WebAssembly program in Rust**

In this example, our Rust program appends the input string after “hello”. Let’s create a new `cargo` project. Since this program is intended to be called from a host application, not to run as a stand-alone executable, we will create a `hello` project.

```
$ cargo new --lib hello
$ cd hello
```

Edit the `Cargo.toml` file to add a `[lib]` section. It tells the compiler where to find the source code for the library and how to generate the bytecode output. We also need to add a dependency of `wasm-bindgen` here. It is the utility `wasm-pack` uses to generate the JavaScript binding for the Rust WebAssembly program.

```
[lib]
name = "hello_lib"
path = "src/lib.rs"
crate-type =["cdylib"]

[dependencies]
wasm-bindgen = "0.2.50"
```

Below is the content of the Rust program `src/lib.rs`. You can actually define multiple external functions in this library file, and all of them will be available to the host JavaScript app via WebAssembly. The `#[wasm_bindgen]` tag instructs the build tools to generate communication interfaces both in Rust / WebAssembly and in the JavaScript module.

```
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn say(s: String) -> String {
  let r = String::from("hello ");
  return r + &s;
}
```

Next, you can compile the Rust source code into WebAssembly bytecode and generate the accompanying JavaScript module.

```
$ wasm-pack build --target web
```

The results are the following two files. the `.wasm` file is the WebAssembly bytecode program, and the `.js` file is the JavaScript module.

```
pkg/hello_lib_bg.wasm
pkg/hello_lib.js
```

#### **The JavaScript host**

Let’s switch back to the JavaScript host application. With the generated `hello_lib.js` module, it is very easy to write JavaScript to call WebAssembly functions. After the `import`, the WebAssembly `say()` function now becomes a JavaScript function with the same name. The complete web page source file is [here](https://github.com/second-state/wasm-learning/blob/master/browser/hello/html/index.html).

```
<script type="module">
  import init, { say } from './hello_lib.js';
  async function run() {
    await init();
    var buttonOne = document.getElementById('buttonOne');
    buttonOne.addEventListener('click', function() {
      var input = $("#nameInput").val();
      alert(say(input));
    }, false);
  }
  run();
</script>
```

The `hello_lib_bg.wasm` program is loaded by the `hello_lib.js` module. Put this HTML file and the `hello_lib.js` and `hello_lib_bg.wasm` files on a web server and you can now access the web page to “say hello” to any name you enter on the page.

#### **What’s next?**

So far, we have seen how to access WebAssembly programs from JavaScript hosted in browsers. But as you know, we believe that WebAssembly’s [real potential is on the server-side](/server-side-webassembly/why).


# Access JavaScript from Rust

Use JavaScript modules to access the file system, network, databases, and other system resources

## This page is outdated. Please visit here to see how to [access JavaScript from Rust](https://www.secondstate.io/articles/access-javascript-form-rust/).[ ](https://www.secondstate.io/articles/access-javascript-form-rust/)

In this tutorial, we will show you how to use the [`nodejs-helper`](https://crates.io/crates/nodejs-helper) crate to call Node.js functions from Rust code. Rust functions can now access the file system, network, database, and other system resources from within the WebAssembly container.

{% hint style="info" %}
It is important to note that a better way for Rust programs to access system resources is through the [WebAssembly WASI extension](/server-side-webassembly/enterprise-webassembly/wasi), as well as numerous [host extensions provided by the SSVM](/server-side-webassembly/enterprise-webassembly).
{% endhint %}

{% hint style="success" %}
The source code of the tutorial is [here](https://github.com/second-state/wasm-learning/tree/master/nodejs/nodejs_example).
{% endhint %}

Let's see an example Rust function that gets the system time and prints to the standard output console, all from within a WebAssembly container.

```
#[wasm_bindgen]
pub fn utc_now() {
  let now: String = nodejs_helper::date::utc_string();
  nodejs_helper::console::log("UTC time: ");
  nodejs_helper::console::log(&now);
}
```

## Prerequisite

You must have Node.js installed with the following packages.

```
$ npm i ssvm sync-request better-sqlite3
$ npm i -g wasm-pack
```

In your Rust application, add the following dependency.

```
[dependencies]
wasm-bindgen = "=0.2.61"
nodejs-helper = "0.0.3"
```

## Building and running

Use the following command to build your Rust application for WebAssembly.

```
$ wasm-pack build --target nodejs
```

Now, let's look some concrete examples from the [example project](https://github.com/second-state/wasm-learning/tree/master/nodejs/nodejs_example).

## Example: system time and console

The Rust functions to access the system time and console resources are as follows.

```
#[wasm_bindgen]
pub fn show_now() {
  nodejs_helper::console::log("Timestamp now: ");
  nodejs_helper::console::log(&nodejs_helper::date::timestamp());
}

#[wasm_bindgen]
pub fn utc_now() {
  nodejs_helper::console::log("UTC time: ");
  nodejs_helper::console::log(&nodejs_helper::date::utc_string());
}

#[wasm_bindgen]
pub fn my_time(tz: &str) {
  nodejs_helper::console::log(tz);
  nodejs_helper::console::log(&nodejs_helper::date::format_date("en-US", "long", "numeric", "long", "numeric", tz, "short"));
}
```

The JavaScript code that loads the WebAssembly container and runs the above Rust functions is as follows.

```
const { show_now, utc_now, my_time } = require('../pkg/nodejs_example.js');

show_now();
utc_now();
my_time("America/Chicago");
```

Running the Javascript in Node.js shows the following.

```
$ node date.js
Timestamp now:
1588013800826
UTC time:
Mon, 27 Apr 2020 18:56:40 GMT
America/Chicago
Monday, April 27, 2020, CDT
```

## Example: Sqlite database access

The Rust functions to create, update, and query a Sqlite database on the local file system are as follows.

```
#[derive(Serialize, Deserialize)]
pub struct User {
  pub id: u32,
  pub full_name: String,
  pub created: String,
}

#[wasm_bindgen]
pub fn create_sqlite(path: &str) {
  let sql_create = "
CREATE TABLE users (
  id INTEGER PRIMARY KEY NOT NULL,
  full_name TEXT NOT NULL,
  created DATE NOT NULL
);";
  let sql_insert = "
INSERT INTO users
VALUES
(1, 'Bob McFett', '32-01-01'),
(2, 'Angus Vader', '02-03-04'),
(3, 'Imperator Colin', '01-01-01');";

  nodejs_helper::sqlite3::create(path);
  nodejs_helper::sqlite3::update(path, sql_create);
  nodejs_helper::sqlite3::update(path, sql_insert);
}

#[wasm_bindgen]
pub fn query_sqlite(path: &str) {
  let sql_query = "SELECT * FROM users;";
  let rows: String = nodejs_helper::sqlite3::query(path, sql_query);
  let users: Vec<User> = serde_json::from_str(&rows).unwrap();
  for user in users.into_iter() {
    nodejs_helper::console::log(&(user.id.to_string() + " : " + &user.full_name));
  }
}
```

The JavaScript code that loads the WebAssembly container and runs the above Rust functions is as follows.

```
const { create_sqlite, query_sqlite } = require('../pkg/nodejs_example.js');

create_sqlite("test.sqlite");
query_sqlite("test.sqlite");
```

Running the Javascript in Node.js shows the following.

```
$ node db.js
1 : Bob McFett
2 : Angus Vader
3 : Imperator Colin
```

## Example: HTTP network access

The Rust functions to access web services via HTTP/HTTPS and then save content on the local file system are as follows.

```
#[wasm_bindgen]
pub fn fetch(url: &str) {
  let content = nodejs_helper::request::fetch_as_string(url);
  nodejs_helper::console::log(url);
  nodejs_helper::console::log(&content);
}

#[wasm_bindgen]
pub fn download(url: &str, path: &str) {
  let content = nodejs_helper::request::fetch(url);
  nodejs_helper::fs::write_file_sync(path, &content);
}
```

The JavaScript code that loads the WebAssembly container and runs the above Rust functions is as follows.

```
const { fetch, download } = require('../pkg/nodejs_example.js');

fetch("https://raw.githubusercontent.com/second-state/nodejs-helper/master/LICENSE");
download("https://www.secondstate.io/", "test.html");
```

Running the Javascript in Node.js shows the following.

```
$ node http.js
https://raw.githubusercontent.com/second-state/nodejs-helper/master/LICENSE
MIT License

Copyright (c) 2020 Second State

Permission is hereby granted, free of charge, to any person obtaining a copy
... ...
```

## Example: File system access and performance profiler

The Rust functions in this section read an image file from the local file system, resize it, and write back to the file system. It also uses the Javascript console tool to measure the time spent on each task.

```
#[derive(Serialize, Deserialize)]
#[derive(Copy, Clone, Debug)]
pub struct Dimension {
  pub width: u32,
  pub height: u32,
}

#[derive(Serialize, Deserialize)]
pub struct Picture {
  pub dim: Dimension,
  pub raw: Vec<u8>,
}

#[wasm_bindgen]
pub fn resize_file(input: &str) {
  // Use JSON to pass multiple call arguments
  let p: (Dimension, String, String) = serde_json::from_str(input).unwrap();

  nodejs_helper::console::time("Resize file");
  let raw = nodejs_helper::fs::read_file_sync(&p.1);
  nodejs_helper::console::time_log("Resize file", "Done reading");
  let src = Picture {
    dim: p.0,
    raw: raw,
  };
  let target = resize_impl(&src);
  nodejs_helper::console::time_log("Resize file", "Done resizing");

  nodejs_helper::fs::write_file_sync(&p.2, &target.raw);
  nodejs_helper::console::time_log("Resize file", "Done writing");
  nodejs_helper::console::time_end("Resize file");
}

pub fn resize_impl(src: &Picture) -> Picture {
  // ... use the img crate to resize ...
}
```

The JavaScript code that loads the WebAssembly container and runs the above Rust functions is as follows.

```
const { resize_file } = require('../pkg/nodejs_example.js');

const dim = {
    width: 100,
    height: 100
};

resize_file(JSON.stringify([dim, 'cat.png', `test.png`]));
```

Running the Javascript in Node.js shows the following.

```
$ node image.js
Resize file: 5.603ms Done reading
Resize file: 1506.694ms Done resizing
Resize file: 1507.634ms Done writing
Resize file: 1507.977ms
```

That's it for now. The [`nodejs-helper`](https://crates.io/crates/nodejs-helper) crate is still a work-in-progress. We aim to eventually provide Rust APIs for all common system functions here. You are welcome to [fork and add to it](https://github.com/second-state/nodejs-helper).


# How to Learn Rust Without Installing Any Software

How to use GitHub Actions to learn Rust from your web browser

## This page is outdated. Please visit here to check out how to [learn Rust from your web browser](https://www.secondstate.io/articles/how-to-publish-a-no-code-website-in-10-minutes/).

##

![](/files/-M4suELnO8Iu2gtJ72z3)

In this article, we'll learn how to use GitHub Actions to learn Rust from your web browser. We'll code, build, test, run, and release all from a web page. No software needed! [Learn with GitHub](https://github.com/second-state/learn-rust-with-github-actions/fork).

Rust is one of the hottest programming languages today. [Alpha geeks](https://martinfowler.com/bliki/AlphaGeek.html) love it. It is Stackoverflow's [most beloved programming language](https://www.theregister.co.uk/2019/04/09/stack_overflow_survey/) for the past 4 years in a row.

One of the most unique and beloved features of Rust is its aggressive compiler that helps you ensure correctness and safety before the program even runs. As a result, Rust developers can write highly performant yet safe programs. Rust eliminates whole classes of programming bugs, especially those hard-to-debug runtime bugs.

If you have not tried it, try it! *It is magical.* I believe Rust could be the next Java or Ruby -- the programming language everyone must learn in the future.

However, learning Rust typically requires you to install a bunch of command line tools on your computer. The Rust compiler is slow because the whole Rust paradigm is set up to deeply analyze the source code and find bugs at compile time, instead of crashing at runtime.

Online Rust IDEs, like the [Rust Playground](https://play.rust-lang.org/) and [REPL.it](https://repl.it/languages/rust), are simple tools that do not take full advantages of the Rust ecosystem of third party compiler targets and libraries.

So you might wonder - can I try and learn Rust without having to install all those software packages on my computer?

Well, with GitHub actions, you can! You can learn and experiment with Rust code directly in your web browser. Let's get started!

> GitHub Actions makes it easy to automate all your software workflows, now with world-class CI/CD. Build, test, and deploy your code right from GitHub. Make code reviews, branch management, and issue triaging work the way you want. The source code and workflow actions for the Hello World example can be found in [this GitHub repository](https://github.com/second-state/learn-rust-with-github-actions).

### Hello world <a href="#hello-world" id="hello-world"></a>

First, create a new GitHub repository, and add a Rust source file. Let's add a `src/main.rs` file with the following content.

```
fn main() {
    println!("Hello, world!");
}
```

<img src="https://www.freecodecamp.org/news/content/images/2020/03/Screen-Shot-2020-03-20-at-2.22.33-AM.png" alt="" data-size="original">

Next, go back to the root `/` directory of the GitHub repository, and add a `Cargo.toml` file. This file describes how the Rust cargo system should build and package our project.

```
[package]
name = "hello"
version = "0.1.0"
authors = ["ubuntu"]
edition = "2018"

[dependencies]
```

The `Cargo.toml` file at the root directory of the repository

Now we have a complete Rust project. Let's build and run it now.

### Github actions <a href="#github-actions" id="github-actions"></a>

On GitHub's Actions tab, we can add workflows associated with this project. Those are actions Github automatically performs when certain events occur, such as code push or commit. In our case, we would like GitHub to automatically build and run our `main.rs`, and show us the results.

The workflow actions and their event triggers are defined in `yml` files under the `.github/workflows` directory. You can write your own `yml` files, or pick from one of the ready-made templates.

![The Rust workflow template in GitHub Actions](/files/-M4svXMOJOUhMk19QAe8)

Here we choose the Rust template. GitHub allows you to edit the `rust.yml` file before checking it into the repository.

![The default Rust actions template. You can edit it to your own liking.](/files/-M4svlpCfVncQT6CUskH)

Let's take a minute here to explain how GitHub Actions work. The default `rust.yml` file says that

* Whenever a user pushes code or accepts pull requests into this repository, the actions in this `rust.yml` workflow will be triggered.
* The workflow will create a virtual machine running the latest Ubuntu operating system. On this Ubuntu system, it will then perform the following steps.
* It will checkout the code from the `master` branch.
* It will run the `cargo build --verbose` command to compile and build the Rust code.
* It will run the `cargo test --verbose` command to execute the test cases.
* All the standard and console outputs on the Ubuntu system from the above two commands will be captured by GitHub Actions and displayed on the web.

You can edit the last line in `rust.yml` to perform `cargo run`, which runs the compiled binary program. Our updated `rust.yml` file is as follows.

```
name: Rust

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Build
      run: cargo build --verbose
    - name: Run
      run: cargo run
```

We changed the last line of the default Rust template to cargo run

Now whenever you push code to this repository, the actions in `rust.yml` are performed. You can see the results under the Actions tab.

![Every push to the GitHub repo will trigger the actions to run](/files/-M4svxBhT_0w_YQ3SwTs)

You can click on a result, and click on the build tab to the left to see the details. The build and run sections provide the most relevant details. The Run section shows successful printing of hello world!

![The Run action shows Hello World! printed to the console!](/files/-M4swC9ojoeauw3p6BDP)

Next, you can add third party dependencies in `Cargo.toml`, and build complex Rust applications in main.rs. Every time someone pushes code, we will be able to see the results.

### Test Driven Development (TDD) <a href="#test-driven-development-tdd" id="test-driven-development-tdd"></a>

Of course, very few developers actually run their programs to print text to the console. The `cargo run` above is just a show. In reality, most developers write functions and test cases for those functions. The most frequent task after compiling and building is to run test cases. Let's see how it is done.

Create a new GitHub repository, and then add a `src/lib.rs` file below. As you can see, it defines a Rust function and a few test cases. It can be built and released as a Rust library package.

```
pub fn say(s: &str) -> String {
  let r = String::from("hello ");
  return r + s;
}

#[cfg(test)]
mod tests {
  use super::*;
  
  #[test]
  fn say_hello() {
    let result = say("ssvm");
    assert!(result.contains("hello ssvm"));
  }
}
```

Then, go back to the root `/` directory of the GitHub repository, and add the following `Cargo.toml` file.

```
[package]
name = "hello"
version = "0.1.0"
authors = ["ubuntu"]
edition = "2018"

[lib]
name = "hello_lib"
path = "src/lib.rs"
crate-type =["cdylib"]

[dependencies]
```

Click on the Actions tab and add the default Rust workflow. As you recall, the default Rust workflow ends with `cargo test`, which is exactly what we need here.

![The default Rust workflow actions are what we need here.](/files/-M4swPFARGANEE17ZJaA)

The workflow runs every time new code is pushed into this repository. You can click open a successful build, and see the output from the build and test actions.

![GitHub actions build and test your Rust program](/files/-M4swdULhQHV4CoFDypl)

### What's next <a href="#what-s-next" id="what-s-next"></a>

Now you can experiment with your Rust code, and have GitHub build, test, and run it for you with complete console outputs, for free and without ever leaving your browser!

### Resources <a href="#resources" id="resources"></a>

* [Learn to program in Rust](https://www.rust-lang.org/learn)
* [Learn more about GitHub Actions](https://github.com/features/actions)
* Of course, the best way to run Rust programs on the server is [inside a WebAssembly Virtual Machine](https://cloud.secondstate.io/server-side-webassembly/getting-started). Checkout the open source [Second State VM](https://www.secondstate.io/) for that!
* Learn about the [BUIDL](https://www.secondstate.io/buidl/) online IDE to [code and deploy](http://buidl.secondstate.io/) decentralized web apps on public blockchains


# How to Publish a no-code website in 10 minutes

Easy way to publish a modern looking web site non-tech people can manage and update. All for free!

## This page is outdated. Please visit here to see how to [publish a no-code website in 10 minutes](https://www.secondstate.io/articles/how-to-learn-rust-without-installing-any-software/).&#x20;

In this article, I'll introduce a no-code, no-software and no-cost solution to publishing sophisticated web sites managed by non-technical people. The full codebase is [on GitHub here](https://github.com/second-state/hugo-website/fork).

Sir Issac Newton discovered the law of gravity when practicing “social distancing” during the Plague. What will YOU do? One silver lining of quarantine is that all this free time brings out the entrepreneur spirit and creativity in us.

However, especially because of the quarantine, now more than ever, any new idea or project must have a web site. Traditional CMS solutions like Wordpress, Squarespace, or Wix are difficult to use, look dated, are expensive, or all of the above!

We wanted to create a web site that has a sophisticated look and feel, yet is easy to customize. A non-technical person should be able to edit the source files and see the changes appear on the live web site in a few minutes. Ideally, it should also be free (forever free, not just free-for-now), and can scale to handle millions of visitors if it becomes popular.

Is this possible?

In this short article, I will walk you through a solution based on the Hugo framework, GitHub Pages, and GitHub Actions. You can get up and running with your shiny new website by the end of this article.

> It is so easy that my 9-year-old son did it. He now manages a web site for his fictional country called [Arenztopia](https://www.arenztopia.com/). Check out the [back story](https://medium.com/@michaelyuan_88928/welcome-to-arenztopia-95cc85253163).

## TL;DR <a href="#tl-dr" id="tl-dr"></a>

If you just want to get started with a working web site as soon as possible, first make sure that you have a free GitHub account.

[**Fork this GitHub repository**](https://github.com/second-state/hugo-website/fork) to your own account.

Go to your forked repository, and click on the Actions tab. You will see a message like the one in the picture below. **Click on** the “I understand my workflows …” button.

Go to the Settings tab of your repository, and then scroll down to GitHub Pages. **Re-select** the `gh-pages` from the dropdown for the web site to build.

Go to the Code tab of the repository, open the `config.toml` file, and edit it. **Change** its `title` attribute to something else, and click on the “Commit changes” button at the bottom. We need this step to trigger the workflow at the new repository.

Wait a few minutes, go to the “published at” web address at GitHub Pages and you will see the template web site.

Next, you can customize the site by editing the `config.toml` file and the files in the `content` folder. Go to the “Add your own content” section at the end of this article to see how. You can check out [the instructions for the Ananke theme here](https://github.com/budparr/gohugo-theme-ananke#getting-started).

That’s it for the quick start! In the next several sections, I will explain in more detail the concepts and processes.

## Hugo basics <a href="#hugo-basics" id="hugo-basics"></a>

Older generation CMS solutions like Wordpress are too difficult to adapt to new web site designs, and commercially hosted solutions like SquareSpace are too expensive and not flexible enough. Static web site generators like Hugo offer a good balance among features, flexibility, and ease of authoring.

* Hugo web sites can be customized and modified through configuration files.
* New pages and content sections can be written in markdown instead of HTML. That makes content authoring much easier.
* There are many modern design themes to choose from.
* The output of Hugo is a static HTML web site that can be deployed on any low-cost hosting provider.
* Together with static web site hosting services like GitHub Pages and Netlify, they can offer a completely free solution.

The Hugo software distribution is [available](https://gohugo.io/getting-started/installing/) on all major operating systems. You can [learn about it here](https://gohugo.io/getting-started/quick-start/). But, since we will use GitHub Actions to automatically build our Hugo web sites, we do not actually need to install Hugo software here.

Here is how to do it.

## Create a template website <a href="#create-a-template-website" id="create-a-template-website"></a>

First, select a Hugo theme. There are [many](https://themes.gohugo.io/). Some are geared toward web sites with one or more content web pages, while others are optimized for blog-like sites with timestamped posts.Hugo themes

Find one you like, download a zip package or clone a GitHub repo, and unpack the theme into a folder. Let’s assume that the theme distribution is unpacked into a folder called `my-theme`. The following are commands in a Linux terminal. You could use the Terminal app on Mac or PowerShell on Windows.

Next, create your web site project directory on your computer.

```
$ mkdir -r my-site/themes
```

Copy the theme folder into your project.

```
$ cp -r my-theme my-site/themes
```

Next, copy the theme’s `exampleSite` to the project’s top-level directory.

```
$ cd my-site
$ cp -r themes/my-theme/exampleSite/* ./
```

Edit the `config.toml` in the project root directory `my-site/`  to point to the right theme.

```
baseURL = "/"themesDir = "themes"theme = "my-theme"
```

Next, create a GitHub repo called `my-site`, and push the `my-site` directory onto its `master` branch. Here are the steps for [uploading files from GitHub’s web UI](https://help.github.com/en/github/managing-files-in-a-repository/adding-a-file-to-a-repository). Now we are ready to publish the theme example site.

For a Hugo-based system to be useable to a non-developer (or a young developer who has yet to master the command line tools), we must automate the process of building and deploying the static web site.

## Automate deployment <a href="#automate-deployment" id="automate-deployment"></a>

In the GitHub project, go to Settings and enable GitHub Pages. Select the source to be the `gh-pages` branch.Settings, GitHub Pages

Next, we create a GitHub Actions workflow to run the Hugo command on the source files from `master` branch, and push the generated HTML files to the `gh-pages` branch for publication. From the project’s Actions tab, click on the “set up a workflow yourself” button.Set up a workflow yourself

The workflow is stored in the `master` branch as `.github/workflows/main.yml` file. The content of the file is as follows.

```
name: github pages

on:
  push:
    branches:
      - master

jobs:
  deploy:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v1  # v2 does not have submodules option now
        # with:
        #   submodules: true

      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: '0.62.2'
          extended: true

      - name: Build
        run: hugo

      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./public
```

What happens here is that the web site authors and editors will change content and files on the `master` branch. Whenever new content is pushed to the `master` branch, the automated GitHub Actions workflow will [set up the Hugo software](https://github.com/peaceiris/actions-hugo/blob/master/README.md), run the `hugo` command, and turn those files into HTML files for a static web site.

The HTML files are [pushed](https://github.com/peaceiris/actions-gh-pages/blob/master/README.md) to the `gh-pages` branch of the same repository. They will be published on the specified web address by GitHub Pages as configured.

Notice the `cname` attribute in the last line. That is the [custom domain name](https://help.github.com/en/github/working-with-github-pages/configuring-a-custom-domain-for-your-github-pages-site) we set up with GitHub Pages. If you do not have a custom domain name, just remove this line, and you can access your web site at the domain provided by GitHub Pages.

Now go to the web site, and you should see the theme’s default web page.The HugoSerif template for one of our web sites.

![The HugoSerif template for one of our web sites.](/files/-M4sxv4ewONW_4VYNdqm)

h

## Add your own content <a href="#add-your-own-content" id="add-your-own-content"></a>

To change the default theme web site to your own content, you just need to change the files on the `master` branch. Please refer to the [documentation](https://gohugo.io/content-management/organization/) of your selected theme. In general, Hugo templates work like this:

* The web pages are authored in markdown format and the `md` files are in the `content` folder.
* Each `md` file has a header section with properties such as the page’s menu placement, priority, timestamp, excerpt, etc.
* The overall configuration, such as the menu items and properties used by multiple pages, are stored in the `data` folder.
* Static content such as raw HTML files, JavaScript files, and image files can be placed in the `static` folder.

In particular, here is how you customize the Ananke theme that comes with our template:

* The [config.toml](https://github.com/second-state/hugo-website/blob/master/config.toml) file allows you to configure the website title, social icons on all pages, and the big featured image on the home page.
* All images should be uploaded to the [static/images](https://github.com/second-state/hugo-website/tree/master/static/images) folder.
* The [content/\_index.md](https://github.com/second-state/hugo-website/blob/master/content/_index.md) file contains the text for the home page.
* To add pages to the site, you can just create [markdown](https://guides.github.com/features/mastering-markdown/) files in the [content](https://github.com/second-state/hugo-website/tree/master/content) folder. An example is the [contact.md](https://github.com/second-state/hugo-website/blob/master/content/contact.md) file. Notice that at the top of the file, there are attributes to control whether this page should be on the website menu.
* To add articles to the site, you can create markdown files in the [content/post](https://github.com/second-state/hugo-website/tree/master/content/post) folder. Those are blog-like content articles that have dates and titles at the top. The most recent two articles will show up on the home page.

If you are interested in learning more and see how we did it, you can watch our progress at

* The Country of Arenztopia \[[GitHub](https://github.com/juntao/arenztopia)] \[[Web site](https://www.arenztopia.com/)]
* Second State blog \[[GitHub](https://github.com/second-state/blog)] \[[Web site](https://blog.secondstate.io/categories/en/)]

Good luck and stay healthy!


