Virke Run
Run JavaScript/TypeScript or Rust at the edge on dedicated Fastly Compute services. Build APIs, server-side rendering, and real-time processing with sub-millisecond warm response times.
Performance
| Metric | JavaScript/TypeScript | Rust |
|---|---|---|
| Cold start | 50–200ms | 10–50ms |
| Warm response | 1–5ms | < 1ms |
| Binary size | ~2–5 MB | ~500 KB–1.8 MB |
Quick Start
Create a compute project
mkdir my-api && cd my-api
virke init --type compute
Write your first edge function
Create src/worker.ts:
import { Hono } from "hono";
import { virke } from "@virke/runtime/hono";
const { fire, middleware, Bindings } = virke({});
const app = new Hono<{ Bindings: typeof Bindings }>();
app.use("*", middleware);
app.get("/", (c) => c.json({ message: "Hello from the edge!" }));
app.get("/headers", (c) => {
return c.json({
ip: c.req.header("Fastly-Client-IP"),
geo: c.req.header("X-Geo-Country"),
pop: c.req.header("X-Served-By"),
});
});
fire(app);
Deploy
virke deploy
JavaScript / TypeScript
Virke Run uses Hono as the recommended web framework, with the @virke/runtime/hono adapter providing Virke-specific bindings.
bun add hono @virke/runtime
Hono adapter
The virke() function returns three things:
fire— Starts the Fastly Compute fetch handlermiddleware— Hono middleware that injects Virke bindings intoc.envBindings— TypeScript type forc.env
Full-stack example
import { Hono } from "hono";
import { virke } from "@virke/runtime/hono";
const { fire, middleware, Bindings } = virke({
db: "my-app-db",
kv: "my-app-kv",
os3: "my-app-assets",
});
const app = new Hono<{ Bindings: typeof Bindings }>();
app.use("*", middleware);
// Database queries
app.get("/users", async (c) => {
const result = await c.env.db.query("SELECT * FROM users");
return c.json(result.rows);
});
// KV cache
app.put("/cache/:key", async (c) => {
const body = await c.req.text();
await c.env.kv.set(c.req.param("key"), body, { ttl: 3600 });
return c.json({ ok: true });
});
// File uploads
app.put("/files/:key", async (c) => {
const body = await c.req.arrayBuffer();
await c.env.os3.put(c.req.param("key"), body);
return c.json({ ok: true });
});
fire(app);
Without Hono (addEventListener style)
import { virkeEnv } from "@virke/runtime";
const env = virkeEnv({ db: "my-db", kv: "my-kv" });
addEventListener("fetch", async (event) => {
const url = new URL(event.request.url);
if (url.pathname === "/users") {
const result = await env.db.query("SELECT * FROM users");
event.respondWith(
new Response(JSON.stringify(result.rows), {
headers: { "Content-Type": "application/json" },
})
);
return;
}
event.respondWith(new Response("Not Found", { status: 404 }));
});
Rust
use fastly::{Error, Request, Response};
#[fastly::main]
fn main(req: Request) -> Result<Response, Error> {
match (req.get_method_str(), req.get_path()) {
("GET", "/") => {
let body = serde_json::json!({
"message": "Hello from the edge!",
"pop": req.get_header_str("X-Served-By")
.unwrap_or("unknown"),
});
Ok(Response::from_body(body.to_string())
.with_content_type(fastly::mime::APPLICATION_JSON))
}
_ => Ok(Response::from_status(404)),
}
}
Accessing Storage
| Binding | Access Pattern | Latency |
|---|---|---|
env.db |
SQL via service chaining to virke-api | 9–120ms reads, 430+ms writes |
env.kv |
Direct Fastly KV Store SDK | 4–10ms reads, ~450ms writes |
env.os3 |
SigV4-signed HTTP to Object Storage | 2–12ms reads (cached) |
virke.toml Configuration
[project]
name = "my-api"
[compute]
entry = "src/worker.ts" # entry point file
language = "javascript" # "javascript" or "rust"
# Optional: attach storage resources
[database]
name = "my-api-db"
[kv]
namespace = "my-api-kv"
[storage]
bucket = "my-api-assets"
Local Development
virke dev # starts Viceroy (Fastly's local emulator)
virke dev --port 8080 # custom port
Canary Deployments
Compute projects support canary deployments using Fastly's native service versioning.
virke canary start-compute <weight> # start with % traffic
--service-version <version> # Fastly service version (required)
--no-sticky # disable sticky sessions
virke canary adjust <weight> --compute # adjust traffic
virke canary promote --compute # promote canary version
virke canary abort --compute # revert to stable
virke canary status # show canary status
Further Reading
- Framework Support — Next.js, SvelteKit, Remix, and Astro adapters
- Virke Components — Portable WebAssembly Component Model
- Virke Cron — Schedule recurring tasks on Virke Run projects
- Virke DB — Using Virke DB from edge functions
- Virke KV — Using Virke KV from edge functions
- Virke OS3 — Using Virke OS3 from edge functions
- CI/CD Guide — Automated deployment for Virke Run projects