Streamlining WebAssembly Development With Spin JavaScript SDK

Semaphore
7 min readMay 9

--

Fermyon Spin has become one of the best WebAssembly frameworks. Spin makes the development of your microservice applications faster, more portable, and even more scalable. Spin supports languages like Rust, TypeScript, Go, C/C++, C#, Zig, Ruby, Python, Grain, and even JavaScript. In this article, we will be focusing on Spin JavaScript SDK, which was introduced in December 2022. With Spin JavaScript SDK, you can now build microservice applications.

In this post, we will dig into building a real-world application with the new Spin JS SDK. We will move from installing Spin and its plugins to building a Spin application. It’s pretty easy, but we will delve into the process in this article. We will also discuss how we can make use of the Some-Random-API service to help fetch some random anime quotes.

Prerequisites

Here are some things you should know before reading this article:

  • Basic knowledge of how to use JavaScript.
  • npm >= 8.5.5 or higher installed on your local development machine.
  • Basic knowledge of how to use APIs.

Getting Started

You need to have everything listed above before diving into things. As we said earlier, we will be using Spin JavaScript SDK to build a random anime quote generator. Firstly, let’s get started by installing Spin on MacOS. We will install the latest version (v1.0.0). This is the first step because the application we’re about to create will also run on Spin. You can download Spin using this link. Alternatively, you can install Spin on your CLI by following these instructions:

  • Run the command below on your terminal to install Spin on your machine:
$ wget https://github.com/fermyon/spin/releases/download/v1.0.0/spin-v1.0.0-macos-aarch64.tar.gz # for Silicon 
$ tar xfv spin-v1.0.0.tar.gz
$ ./spin --help

After installing Spin, make sure to add it to your machine’s main path so that you can access it from any directory, as shown below

sudo mv ./spin /usr/local/bin/spin

By doing this, you do not have to install Spin in every single directory you want to work on.

Working with Spin JavaScript SDK

Now that we have installed Spin and made it accessible in every directory, we can get started with building with Spin JavaScript SDK, but before doing that, note that Spin JavaScript SDK is experimental and that it even supports TypeScript–if you use TypeScript, this SDK is for you too. Working with Spin JS SDK means you’re just working with JavaScript and other Spin components. Now, let’s start by installing the js2wasm plugin. We will now have to run the following command to install the plugin:

$ spin plugin update
$ spin plugin install js2wasm

The first command spin plugin update helps update the default Spin plugin. For the second command, it calls out Spin to install the js2wasm plugin. The js2wasm plugin aids in the conversion of JavaScript code into WebAssembly and its execution in the browser.

What we’ll do next is install the Spin JS template, and you have to do that right in your Spin CLI with the following command:

$ spin templates install --git https://github.com/fermyon/spin-js-sdk
Copying remote template source
Installing template http-ts...
Installing template http-js...
Installed 2 template(s)
+-------------------------------------------------+
| Name Description |
+=================================================+
| http-js HTTP request handler using Javascript |
| http-ts HTTP request handler using Typescript |
+-------------------------------------------------+

The command above also installs the JavaScript and TypeScript template from its source, so in this case, you can choose to use TypeScript or JavaScript to build your Spin application, whichever way works! Now that you have installed the template, the next thing for you to do is utilize it.

For JavaScript, here’s how to create a project from the template you installed earlier on:

$ spin new http-js my-project --accept-defaults

If you’re done doing this, you should run the cd my-project command to locate the directory you created for the project. After doing this, you can run the code . command to open the project in Visual Studio Code. And if you’re not using VSCode, just open your IDE and locate the project path manually.

Alternatively, if you’re using TypeScript, here’s how you can create your project:

$ spin new http-ts my-project --accept-defaults

You can also follow the same instructions as for JavaScript if you want to start with TypeScript. This article is focused on JavaScript, so we will continue with JavaScript. Now that you’ve opened the project in Visual Studio Code, you should get this:

![Spin JS Project on Visual Studio Code](https://cdn.hashnode.com/res/hashnode/image/upload/v1676029514927/7a7c9827-454d-4122-aa2c-f4d1e2a27ef9.png align=”center”)

You can now examine all of the code. First, you can navigate to the spin.toml file, which is the configuration file for Spin, and you can see every necessary piece of information about the project and its settings. You can also check the webpack.config.js file; the configuration file for the JavaScript code. What we will be working with is the index.js file in the src/ directory; this is where you will write all of your JavaScript code.

You can now check the src/index.js file, and you’ll find the following code:

const encoder = new TextEncoder()
export async function handleRequest(request) {    return {
status: 200,
headers: { "foo": "bar" },
body: encoder.encode("Hello from JS-SDK").buffer
}
}

Now that you can see this code, you’ll see that its output should just be “Hello from JS-SDK.” But first, let’s use the terminal to install all of the dependencies by running the following command:

$ npm install

Next, you should wait a few seconds until the dependencies are installed before running the following command:

$ npm run build

After doing this, you could be asking yourself a very big question: “Why am I installing npm in a Spin project?” It’s essential, as we need it to run your JavaScript code. You’ll also notice that it’s included in the package.json and package.lock.json files.

Finally, to run your application, run the following command:

$ spin up
Serving http://127.0.0.1:3000
Available Routes:
my-project: http://127.0.0.1:3000 (wildcard)

This should be the output of your code in the browser after running the application.

![Hello from JS-SDK](https://cdn.hashnode.com/res/hashnode/image/upload/v1676052466130/2a308402-46e2-49d1-8c90-7caf6f3d86a5.png align=”center”)

Now, as you can see, the code in the src/index.js file prints out this text in your browser.

Developing the Random Anime Quotes Generator

Funnily enough, this will be done in the same src/index.js file but using a different concept. Now, we will build a JavaScript application that fetches random anime quotes from the Some Random API platform.

First, get into your spin.toml file. In the [[component]] configuration, you should have the following code:

[[component]]
id = "sample-gen"
source = "target/spin-http-js.wasm"
exclude_files = ["**/node_modules"]
allowed_http_hosts = ["https://some-random-api.ml"]
files = ["src/index.html"]
[component.trigger]
route = "/..."
[component.build]
command = "npm run build"

The only changes you’ll notice is that allowed_http_hosts = ["https://some-random-api.ml"] and files = ["src/index.html"]have been added. The allowed_http_hosts component trigger calls out the API service we will be using, which allows the API in the src/index.js file to start working.

Now, let’s head to the src/index.js file and get started. Go ahead and add the following code:

const encoder = new TextEncoder("utf-8")
const decoder = new TextDecoder("utf-8")

The TextEncoder helps convert all strings to bytes, so we need to include that first. Its counterpart, TextDecoder, helps to decode the UTF-8 strings. Rewrite the handleRequest() as follows:

export async function handleRequest(request) {
const Quote = await fetch("https://some-random-api.ml/animu/quote")
    const QuoteBody = decoder.decode(await Quote.arrayBuffer() || new Uint8Array())    const body = `Here's a Quote: ${QuoteBody}\n`}

We just used the async function in the first line of code and added the handleRequest function; this serves as an entry point for the Spin component in this case. In the next line, we are trying to call out the API’s endpoint. Meanwhile, in the other lines, we’re trying to structure the response after fetching the API.

Now, add this code before the closing bracket:

return {
status: 200,
headers: { "foo": "bar" },
body: encoder.encode(body).buffer
}

This code is just to print the response of the API you fetch, so the whole code in the src/index.js file should appear as shown below:

const encoder = new TextEncoder("utf-8")
const decoder = new TextDecoder("utf-8")
export async function handleRequest(request) {
const Quote = await fetch("https://some-random-api.ml/animu/quote")
const QuoteBody = decoder.decode(await Quote.arrayBuffer() || new Uint8Array())

const body = `Here's a Quote: ${QuoteBody}\n`
return {
status: 200,
headers: { "foo": "bar" },
body: encoder.encode(body).buffer
}
}

Now, you can run the spin build command, which also executes the npm run build command. After doing that, run the spin up command, and you should have random anime facts in your browser just like this:

![A result of the random anime quote generator] (https://cdn.hashnode.com/res/hashnode/image/upload/v1676105458188/371d3166-e78d-421b-a74b-c7280bd87c2f.png align=”center”)

Perfect! Now, you have your Spin application running, and we’re finished.

Conclusion

I hope that you had fun learning how to build a Spin application with Spin JavaScript SDK. Even though this tutorial only covers building a random anime quote generator with Spin JavaScript SDK, there’s a lot more you can do with Spin. For example, you can build a WASM todo list app, a simple spin application for serving doom-wasm, or you could even build a game just like Finicky Whiskers. Thanks for stopping by to read this article. You can also check out this sample code on GitHub.

If you have any questions, you can leave them in the comments section below.

Originally published at https://semaphoreci.com on May 9, 2023.

--

--

Semaphore

Supporting developers with insights and tutorials on delivering good software. · https://semaphoreci.com