The Spin JS/TS SDK consists of three parts:
- A Spin plugin, called
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.
Let’s build a simple “hello, world” app using TypeScript, starting from the
js2wasm plugin, and the
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
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:
For more examples, including React SSR, PlanetScale, and Redis, check out the examples directory of the SDK repository.
js2wasm: Under the Hood
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
fetch Web APIs, while the filesystem API mirrors Node’s
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.
For more details on how to get started with Spin, Fermyon Cloud, and the JS/TS SDK, check out the following resources: