Skip to content

Introduction

Build, run, and deploy WASI HTTP handlers

mik is a batteries-included CLI for WASI HTTP projects. It handles building, composition, and running your WASM HTTP handlers with reliability features like circuit breakers, rate limiting, and JavaScript orchestration.

Note: mik is an experimental project for learning WASI P2 and the component model. Not yet battle-tested for production.

Challengemik Solution
Complex WASI runtimesSingle binary with embedded runtime
No built-in reliabilityCircuit breaker, rate limiting, caching
Orchestration requires RustJavaScript/TypeScript via rquickjs
Multi-module scenariosRoute multiple handlers from one server
  • Single Binary - mik CLI includes the embedded runtime
  • Reliability - Circuit breaker, rate limiting, graceful shutdown
  • LRU Cache - Byte-aware module caching with configurable limits
  • JavaScript Orchestration - Compose multiple WASM handlers via JS/TS scripts
  • Static Files - Optional static file serving with MIME detection
  • Prometheus Metrics - Built-in /metrics endpoint
  • Gzip Compression - Automatic compression for large responses
Terminal window
# Install
cargo install mik
# Create project
mik new my-api
cd my-api
# Build and run (dev mode with watch + services)
mik build -rc
mik dev

Test: curl http://localhost:3000/run/my-api/

Run multiple handlers from a directory:

Terminal window
mik run # Uses mik.toml configuration
[server]
modules = "modules/"
RouteHandler
/run/auth/*modules/auth.wasm
/run/users/*modules/users.wasm
/run/orders/*modules/orders.wasm
/static/*Static files (if configured)
/healthHealth check
/metricsPrometheus metrics

Run a single component:

Terminal window
mik run dist/my-api-composed.wasm

Routes: /run/my-api/* -> component (name derived from filename)

Write handlers with typed, ergonomic Rust macros:

#[allow(warnings)]
mod bindings;
use bindings::exports::mik::core::handler::{self, Guest, Response};
use mik_sdk::prelude::*;
#[derive(Path)]
struct UserPath {
id: u32,
}
routes! {
GET "/" | "" => home,
GET "/users/{id}" => get_user(path: UserPath),
}
fn home(_req: &Request) -> Response {
ok!({
"message": "Hello from mik!",
"version": "0.1.0"
})
}
fn get_user(path: UserPath, _req: &Request) -> Response {
ok!({
"id": path.id,
"name": "Alice"
})
}
  • Rust 1.85+
  • cargo-component for building WASM
  • wac-cli for composition

MIT