Introducing the Spin JavaScript and TypeScript SDK
Joel Dice
javascript
typescript
spin
sdk
We’re pleased to announce a new experimental SDK for building Spin applications, supporting the two most popular languages for web development: JavaScript and TypeScript.
In this post, we’ll explain how to use the SDK in combination with familiar tools like NPM and Webpack to build rich serverless apps, including features like React server-side rendering, cloud database access, and outbound HTTP requests. In addition, we’ll look behind the scenes at how the SDK translates JavaScript code to WebAssembly and provides familiar, NodeJS-style APIs for accessing the filesystem, reading environment variables, etc.
Introduction
The Spin JS/TS SDK consists of three parts:
- A Spin plugin, called
js2wasm
, which takes a JavaScript file as input and produces a Spin-compatible WebAssembly module as output. You can install it using spin plugin install js2wasm
.
- An optional NPM package, called
spin-sdk
, which provides TypeScript type declarations describing the classes, functions, etc. provided by the SDK. You can add it to your app using npm install @fermyon/spin-sdk
.
- A couple of Spin templates for quickly starting a new JS or TS project. These can be installed using
spin templates install --git https://github.com/fermyon/spin-js-sdk
.
Hello, World!
Let’s build a simple “hello, world” app using TypeScript, starting from the http-ts
template.
First, install spin
, the js2wasm
plugin, and the http-js
and http-ts
templates:
curl -fsSL https://developer.fermyon.com/downloads/install.sh | bash
sudo mv ./spin /usr/local/bin/spin
spin plugin install js2wasm
spin templates install --git https://github.com/fermyon/spin-js-sdk
Next, use the http-ts
template to create a new project called hello
:
spin new --accept-defaults http-ts hello
Finally, build and run it:
npm install
npm run build
spin up
While it’s running, use your browser or cURL in another shell to try it out:
curl -i 127.0.0.1:3000/hello
You can edit src/index.ts using your favorite editor or IDE, split your app into multiple modules, add new dependencies with npm install
, etc. When you’re happy with it, you can either deploy it to your own infrastructure using Fermyon Platform or else to your free Fermyon Cloud account. The following command will prompt you to log in with your GitHub account if you haven’t already, then deploy your app to Fermyon Cloud, and finally print the URL you can use to access it and share with others:
spin deploy
For more examples, including React SSR, PlanetScale, and Redis, check out the examples directory of the SDK repository.
js2wasm
: Under the Hood
If you’ve done backend JavaScript and/or TypeScript development in the past, you’re probably familiar with popular JS runtimes such as Node and Deno. Spin, on the other hand, is based on Wasmtime, a language-agnostic WebAssembly runtime, which means it has no built-in support for running JS modules. In order to convert JS code to a WebAssembly module Spin can run, we use the js2wasm
plugin.
js2wasm
is based on Shopify’s excellent Javy project, which provides a single step conversion from JS code to a WebAssembly module. It bundles your application’s JS code with a lightweight JS interpreter called QuickJS and pre-initializes it to ensure quick, sub-millisecond startup times.
The main advantage of running your JS code this way instead of using a traditional runtime like Node is that each incoming HTTP request is handled in its own isolated sandbox for security. The main disadvantage, at least for the time being, is that QuickJS can’t match the performance of e.g. V8’s tiered just-in-time (JIT) compiler for CPU-intensive applications; see these benchmarks for details. However, there is work ongoing to support ahead-of-time (AOT) compilation from JS to Wasm using Mozilla’s SpiderMonkey project which should help close that gap.
Built-in SDK Features
QuickJS supports nearly all of the ES2020 standard library, including the math, date, and text processing functions and data structures JS programmers are accustomed to. In addition, the SDK includes built-in APIs for filesystem operations, environment variables, outbound HTTP requests, etc. Where applicable, we’ve modeled these APIs on existing popular libraries and runtimes. For example, the outbound HTTP API matches the standard URL
and fetch
Web APIs, while the filesystem API mirrors Node’s readFile
and readdir
functions.
Currently, the SDK only implements a small subset of the standard Web and Node APIs. This is partly because the Spin application sandbox is designed for stateless, “serverless”-style applications where e.g. write access to files is not permitted, and partly because the SDK is still under development. If you have a use case that depends on a standard API which the SDK does not yet support, please feel free to open an issue.
Conclusion
We’re excited to add JavaScript and TypeScript to the list of languages you can use to build Spin applications. These languages are a natural fit for serverless applications, backed by a vast ecosystem of packages and mature, familiar tools such as NPM and Webpack. The Spin JS/TS SDK is designed to integrate seamlessly with those tools, empowering developers to quickly and easily build, test, and deploy secure serverless apps.
Next Steps
For more details on how to get started with Spin, Fermyon Cloud, and the JS/TS SDK, check out the following resources: