Spin is Fermyon's framework for building WebAssembly (Wasm) microservices. Write a function in Rust, TypeScript, Python, or Go — Spin compiles it to Wasm and deploys it with sub-millisecond cold starts.
Why Spin Matters
Containers take seconds to start. Lambda functions take hundreds of milliseconds. WebAssembly components start in under 1 millisecond. Spin makes building Wasm microservices as easy as writing a function.
What you get for free:
- Sub-millisecond cold starts (vs seconds for containers)
- Write in Rust, TypeScript, Python, or Go
- Built-in key-value store, SQLite, and Redis integrations
- Fermyon Cloud: deploy with
spin deploy(free tier available) - Component model: compose microservices from Wasm components
- Security: sandboxed execution by default
Quick Start
# Install
curl -fsSL https://developer.fermyon.com/downloads/install.sh | bash
# Create project
spin new -t http-ts my-api
cd my-api
# Run locally
spin build && spin up
# Deploy to Fermyon Cloud
spin deploy
HTTP Handler (TypeScript)
import { HandleRequest, HttpRequest, HttpResponse } from "@fermyon/spin-sdk";
export const handleRequest: HandleRequest = async (request: HttpRequest): Promise<HttpResponse> => {
const url = new URL(request.uri, "http://localhost");
const name = url.searchParams.get("name") || "World";
return {
status: 200,
headers: { "content-type": "application/json" },
body: JSON.stringify({
message: `Hello, ${name}!`,
runtime: "WebAssembly",
coldStart: "<1ms",
}),
};
};
Built-in Key-Value Store
import { Kv } from "@fermyon/spin-sdk";
export const handleRequest: HandleRequest = async (request) => {
const store = Kv.openDefault();
if (request.method === "POST") {
const body = JSON.parse(new TextDecoder().decode(request.body));
store.set(body.key, JSON.stringify(body.value));
return { status: 201, body: "Stored" };
}
if (request.method === "GET") {
const url = new URL(request.uri, "http://localhost");
const key = url.searchParams.get("key");
const value = store.get(key!);
return {
status: 200,
headers: { "content-type": "application/json" },
body: new TextDecoder().decode(value!),
};
}
return { status: 405, body: "Method not allowed" };
};
Built-in SQLite
import { Sqlite } from "@fermyon/spin-sdk";
export const handleRequest: HandleRequest = async (request) => {
const db = Sqlite.openDefault();
db.execute(
"CREATE TABLE IF NOT EXISTS visits (id INTEGER PRIMARY KEY, path TEXT, timestamp TEXT)",
[]
);
const url = new URL(request.uri, "http://localhost");
db.execute(
"INSERT INTO visits (path, timestamp) VALUES (?, ?)",
[url.pathname, new Date().toISOString()]
);
const results = db.execute("SELECT COUNT(*) as count FROM visits", []);
const count = results.rows[0]["count"];
return {
status: 200,
body: JSON.stringify({ totalVisits: count }),
};
};
Rust Handler (Maximum Performance)
use spin_sdk::http::{IntoResponse, Request, Response};
use spin_sdk::http_component;
#[http_component]
fn handle_request(req: Request) -> anyhow::Result<impl IntoResponse> {
let body = serde_json::json!({
"message": "Hello from Rust + Wasm!",
"method": req.method().to_string(),
"path": req.uri().path(),
});
Ok(Response::builder()
.status(200)
.header("content-type", "application/json")
.body(body.to_string())?)
}
Cold Start Comparison
| Platform | Cold Start | Memory |
|---|---|---|
| Spin (Wasm) | <1ms | 1-10MB |
| AWS Lambda | 100-500ms | 128MB+ |
| Docker | 1-5s | 50MB+ |
| Kubernetes Pod | 5-30s | 100MB+ |
Useful Links
- GitHub
- Documentation
- Fermyon Cloud — free tier
- Component Examples
Building serverless data pipelines? Check out my developer tools on Apify for ready-made web scrapers, or email spinov001@gmail.com for custom solutions.
Top comments (0)