Browse Chapters

Creating Serverless Apps

Each serverless platform has its own way for creating apps. For example, Amazon’s Lambda has a lengthy set of steps for you to go through to create a first function.

Later in this post, we’ll run through a quickstart using Spin, which will get us testing our first Spin serverless app in less than two minutes. But here is a list of guides for various serverless platforms:

A First Serverless App with Spin

While each platform has its own way of doing things, we’ll walk through a basic Spin example using JavaScript. This will give an idea of what a simple serverless function looks like.

We’ll assume you have installed Spin.

1. Create a new app

Creating a new app with Spin is as easy as typing spin new and answering a few questions. We’re going to create a new JavaScript app:

$ spin new my-spin-app
Pick a template to start your application with:
  http-c (HTTP request handler using C and the Zig toolchain)
  http-empty (HTTP application with no components)
  http-go (HTTP request handler using (Tiny)Go)
  http-grain (HTTP request handler using Grain)
> http-js (HTTP request handler using Javascript)
  http-php (HTTP request handler using PHP)
  http-prolog (HTTP request handler using Trealla Prolog)
  http-py (HTTP request handler using Python)
  http-rust (HTTP request handler using Rust)
  http-swift (HTTP request handler using SwiftWasm)
  http-ts (HTTP request handler using Typescript)
  http-zig (HTTP request handler using Zig)
  kv-explorer (Explore the contents of Spin KV stores)
  php (HTTP PHP environment)
  redirect (Redirects a HTTP route)
  redis-go (Redis message handler using (Tiny)Go)
  redis-rust (Redis message handler using Rust)
  static-fileserver (Serves static files from an asset directory)
Description: Test app with Spin 2.6
HTTP path: /...

Now we have a new directory called my-spin-app:

$ tree my-spin-app       
my-spin-app
├── README.md
├── package.json
├── spin.toml
├── src
│   └── index.js
└── webpack.config.js

1 directory, 5 files

If we were to look at my-spin-app/src/index.js, this is what we’d see:

export async function handleRequest(request) {
    return {
        status: 200,
        headers: { "content-type": "text/plain" },
        body: "Hello from JS-SDK"
    }
}

That is a complete Spin app. It takes a request (which it doesn’t use) and returns a response, which includes the plain text body “Hello from JS-SDK”.

Our serverless app is ready to build!

2. Build a Wasm binary

With JavaScript, we need to run npm install to set up NPM:

$ cd my-spin-app
$ npm i

added 125 packages, and audited 126 packages in 5s

18 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
npm notice 
npm notice New major version of npm available! 9.8.0 -> 10.8.2
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.8.2
npm notice Run npm install -g npm@10.8.2 to update!
npm notice 

Now we can build our code into a serverless WebAssembly app:

$ spin build
Building component my-spin-app with `npm run build`

> my-spin-app@1.0.0 build
> npx webpack --mode=production && npx mkdirp target && spin js2wasm -o target/my-spin-app.wasm dist/spin.js

asset spin.js 1.86 KiB [emitted] (name: main)
runtime modules 670 bytes 3 modules
./src/index.js 175 bytes [built] [code generated]
webpack 5.93.0 compiled successfully in 51 ms

Starting to build Spin compatible module
Preinitiating using Wizer
Optimizing wasm binary using wasm-opt
Spin compatible module built successfully
Finished building all Spin components

The output of this command is a WebAssembly binary file that includes both the JavaScript engine and our entire app:

$ ls -lah target/my-spin-app.wasm                     
-rw-r--r--  1 user  staff   2.3M Jul 18 14:37 target/my-spin-app.wasm

That’s all there is to building. We can now test locally.

3. Run it locally

The spin up command starts a local instance. This command is also useful if you are running just one Spin app as a stand-alone service on bare metal.

$ spin up
Logging component stdio to ".spin/logs/"

Serving http://127.0.0.1:3000
Available Routes:
  my-spin-app: http://127.0.0.1:3000 (wildcard)

We can access the local URL with either a web browser or with the curl command:

$ curl localhost:3000                                                 
Hello from JS-SDK

That’s all there is to it! We’ve created a simple serverless app, compiled it to WebAssembly, and locally run it. We could immediately take this app and deploy it to Fermyon Cloud using spin deploy, or to a SpinKube Kubernetes cluster with spin k8s deploy.

For more details on how to take our basic app and make it do interesting things, check out the Fermyon Developer site for documentation or the Spin Up Hub for examples.

Browse Chapters

Quickstart Your Serveless Apps with Spin

Get Started