- Published on
WebAssembly サーバーサイドと WASI 2026 徹底解剖 — Spin / Wasmtime / Wasmer / WasmEdge / wasmCloud / Extism / JCO / Component Model 完全ガイド
- Authors

- Name
- Youngju Kim
- @fjvbn20031
プロローグ — 2026 年、WASM は「ブラウザの速いアセンブリ」ではない
Docker 創業者 Solomon Hykes が 2019 年に残したツイートは、いまや引用を越えて現実になった。
「もし 2008 年に WASM+WASI が存在していたら、Docker を作る必要はなかった」
2026 年の WebAssembly は次のとおりだ。
- WASI Preview 2 が 2024 年 1 月に正式リリースされ、2025 年を通じて各ランタイムが P2 互換を完了した。Wasmtime 26+、WasmEdge 0.14+、Wasmer 5+、jco 1.x がすべて P2 コンポーネントを実行する。
- Component Model が安定化し、Rust・Go・JavaScript・Python・Java で書かれたコードが 単一の WIT インターフェース を介して組み合わさる。ポリグロットはもはやスローガンではなく標準だ。
- エッジコンピュートでは WASM が V8 isolate に続く次世代の隔離プリミティブとなった。Cloudflare Workers は WASM を一級バインディングで扱い、Fastly Compute@Edge は最初から WASM の上に作られ、Cosmonic・Fermyon Cloud・Wasmer Edge は WASM 専用 PaaS として育っている。
- Docker Desktop は WASM ワークロードを公式サポートし、
docker run --runtime=io.containerd.wasmedge.v1一行でコンテナなしに WASM を起動する。Kubernetes は RuntimeClass と spin-operator で WASM ワークロードをノードにスケジュールする。 - 組み込みと IoT でも WASM は OTA 更新可能な安全なプラグインモデルとして定着した。Extism がその旗手だ。
本稿はその変化のど真ん中を 24-28 章で整理する。コードはすべて 2026 年 5 月時点で実際に動く形であり、引用 URL もすべて実在する。
一行要約: 「自分のコードはどこで、どんな権限で動くのか、それを誰が組み立てるのか」 — この二つの問いが 2026 年の WASM ツール選びの 90% を決める。
第 1 章 · WASM の本質を再確認 — アセンブリ・隔離・移植性
WebAssembly はしばしば「速いアセンブリ」と紹介されるが、本質は次の三軸だ。
| 軸 | 意味 | 結果 |
|---|---|---|
| Portable bytecode | スタックマシン型の仮想 ISA | 同一バイナリがどこでも動く |
| Sandboxed by default | ホストメモリやシステムコールへ直接触れない | 信頼境界が明確 |
| Deterministic | 浮動小数点 NaN を除けば決定的 | キャッシュ性・再現性が高い |
ブラウザはあくまで第一の舞台だった。2017 年の MVP 以降、コア仕様は reference types、multi-value、bulk memory、SIMD、threads、tail call、GC、exception handling、multi-memory、function references まで拡張された。2026 年現在、GC と exception handling は主要ランタイムで安定化し、その上で Java・Kotlin・OCaml・Dart のような GC 言語が自然にコンパイルされる。
重要な発想転換: 2026 年の WASM は「C/Rust を速く回す VM」ではなく 「言語中立のコンポーネント ABI」 だ。だから次章の Component Model こそが本丸である。
第 2 章 · WASI Preview 1 と Preview 2 — POSIX 模倣からケーパビリティ・インターフェースへ
初期の WASI(WebAssembly System Interface)は POSIX の部分模倣だった。fd_read、fd_write、path_open のような関数が wasi_snapshot_preview1 インターフェースに平坦に並び、Rust の wasm32-wasi ターゲットがそれを呼んでいた。実質「ランタイムが貸してくれた POSIX」である。
WASI Preview 2(WASI 0.2)は違う。
- すべてのインターフェースが WIT(WebAssembly Interface Type) で記述される。平坦な関数列ではなく、interface と world の階層構造 だ。
- 標準 P2 worlds:
wasi:cli/command、wasi:http/proxy、wasi:keyvalue/store、wasi:filesystem/types、wasi:sockets/network、wasi:logging/logging、wasi:clocks/wall-clock、wasi:random/random。 - 各 world は ホストが明示的に import した権限のみ をモジュールに公開する。モジュールがホストのディスクを見たいなら、ホストが
wasi:filesystemを明示的に接続する必要がある。
これがまさに ケーパビリティベースのセキュリティ だ。周囲に漂う権限(ambient authority)は存在しない。モジュールは自分が import したことしかできない。コンテナの seccomp / capabilities / AppArmor よりはるかに明示的でコンポーザブルだ。
P1 → P2 の移行は 2025 年でほぼ完了した。Rust の wasm32-wasip2 ターゲット、TinyGo の wasip2、jco の P2 コンポーネント生成が標準経路である。
第 3 章 · Component Model — 言語中立 ABI という事件
Component Model は WASM に二層を追加する。
- Core module — 従来の .wasm。関数・メモリ・テーブル・グローバル。
- Component — 複数の core module を束ね、WIT 型(record、variant、list、option、result、resource、tuple、string)を外部インターフェースとして公開する。
Component Model が解決したのは 言語間の ABI 調停 だ。C と Rust はメモリを直接扱う。Go は GC を持つ。JavaScript は GC + JIT。これらは互いの関数を直接呼べない。Component Model はその中間に canonical ABI を置き、lift / lower で型を変換する。
WIT インターフェース定義の一片を見てみよう。
package example:greeter@0.2.0;
interface api {
/// 挨拶文を組み立てる。
greet: func(name: string) -> string;
/// カウンタリソース。
resource counter {
constructor();
increment: func();
get: func() -> u64;
}
}
world greeter {
export api;
import wasi:clocks/wall-clock@0.2.0;
import wasi:logging/logging@0.2.0;
}
この WIT 一枚から:
- Rust では
wit-bindgenマクロが trait と実装スタブを生成する。 - JavaScript では
jco transpileが ES モジュールを生成する。 - Go では
wit-bindgen-goが Go パッケージを生成する。 - Python では
componentize-pyが Python コードを WASM コンポーネントに梱包する。
呼び出し側は実装言語を知らない。それが Component Model の約束だ。
第 4 章 · Wasmtime — Bytecode Alliance のリファレンスランタイム
Wasmtime は Bytecode Alliance が手がける WASM の事実上のリファレンス実装である。Rust で書かれ、Cranelift コードジェンを通じて x86_64 / aarch64 / s390x へ AOT / JIT コンパイルする。
2026 年現在、Wasmtime 26.x が安定系列だ。主な特徴:
- WASI Preview 2 完全対応 — wasmtime-wasi クレート。
- Component Model 一級対応 — wasmtime-component クレート。
- Pooling allocator — 数万インスタンス同時起動でも断片化なく再利用。
- Epoch ベースの中断 — 外部から暴走ループを止められる。
- 事前コンパイル(.cwasm) — AOT 成果物で数十マイクロ秒のコールドスタート。
- 非同期サポート — Tokio とシームレスに統合。
Wasmtime の真骨頂はホスト埋め込みのきれいさだ。Rust ホストがコンポーネントをロードして関数を呼ぶ流れ:
use wasmtime::{Engine, Config, Store};
use wasmtime::component::{Component, Linker};
fn main() -> anyhow::Result<()> {
let mut config = Config::new();
config.wasm_component_model(true);
config.async_support(false);
let engine = Engine::new(&config)?;
let component = Component::from_file(&engine, "greeter.wasm")?;
let mut linker = Linker::new(&engine);
wasmtime_wasi::add_to_linker_sync(&mut linker)?;
let wasi = wasmtime_wasi::WasiCtxBuilder::new()
.inherit_stdio()
.build_p1();
let mut store = Store::new(&engine, wasi);
let instance = linker.instantiate(&mut store, &component)?;
let greet = instance.get_typed_func::<(String,), (String,)>(&mut store, "greet")?;
let (out,) = greet.call(&mut store, ("WASI 2026".into(),))?;
println!("{out}");
Ok(())
}
このパターンは Spin・wasmCloud・Lambda Adapter がいずれも内部で変奏している。
第 5 章 · Wasmer — マルチバックエンドとパッケージマネージャとしての WASM
Wasmer は Wasmtime と毛色が違う。最初から 複数のコンパイラバックエンド(Cranelift、LLVM、Singlepass)を選べる設計で、WAPM(WebAssembly Package Manager)という npm 風の配布チャネルも備えている。
2026 年の Wasmer 5.x の強みは次のとおり。
- LLVM バックエンドによる最大性能 — ネイティブの 90% 水準。
- WASIX — Preview 1 を拡張し、スレッド・シグナル・fork・exec・TCP/UDP ソケットまでサポートする独自仕様。POSIX アプリをほぼそのまま動かせる。Python・Bash・Postgres を Wasmer で動かすデモが有名だ。
- Wasmer Edge — Cloudflare Workers と競合する自前のエッジ PaaS。
- JS / Python / PHP 統合 — Wasmer の SDK はホスト言語を選ばない。
Wasmer で Python を動かす一行:
wasmer run python/python --mapdir=/app:./app -- /app/main.py
WAPM は Component Model の上にパッケージを束ねる。2026 年に入って OCI レジストリ(GHCR、Docker Hub)との相互運用が加速し、ghcr.io に WASM コンポーネントを push する標準フローが確立した。
Wasmer の P2 対応は Wasmtime に少し遅れたが 5.x で追いついた。WASIX と P2 を一つのランタイムで扱える点が Wasmer の差別化だ。
第 6 章 · WasmEdge — クラウドネイティブと AI に特化したランタイム
WasmEdge は CNCF Sandbox から Incubating を経て、2025 年に Graduated に近いステータスを得た。CloudOS・CDN・AI 推論に特化した設計が特徴だ。
- AOT(Ahead-of-Time)コンパイル — LLVM ベース。コールドスタートはほぼゼロ。
- Kubernetes ワークロードの一級サポート — containerd-wasm-shims、CRI-O、Docker Desktop、Kubernetes RuntimeClass。
- AI プラグイン — WasmEdge ggml(llama.cpp バックエンド)、PyTorch、TensorFlow Lite、OpenVINO。Llama 3・Mistral・Qwen を WasmEdge で直接推論できる。
- ネットワーキング拡張 — TLS、HTTP/2、QUIC をホストが提供。
- 言語 SDK — Rust、C、Go、Java、Python、JavaScript(QuickJS 統合)。
Docker Desktop 4.x 以降、WasmEdge は docker run --runtime=io.containerd.wasmedge.v1 一行で実行できる。Kubernetes では次のように RuntimeClass を定義する。
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: wasmedge
handler: wasmedge
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-wasm
spec:
replicas: 3
selector:
matchLabels: { app: hello-wasm }
template:
metadata:
labels: { app: hello-wasm }
spec:
runtimeClassName: wasmedge
containers:
- name: hello
image: ghcr.io/example/hello-wasm:0.1.0
WasmEdge は「K8s で WASM を回すいちばん簡単な道」というポジショニングを明確に取っている。
第 7 章 · Spin(Fermyon) — WASM マイクロサービスのフレームワーク
Fermyon の Spin は「WASM 版の Express / Flask」と言ってよい。コンポーネント一つが HTTP ハンドラや Redis コンシューマや cron トリガとして動き、コンポーネント間は WIT で結ばれる。
Spin の中核要素:
- spin.toml — マニフェスト。
- trigger — http、redis、mqtt、cron、sqs、kafka。
- wasi-keyvalue、wasi-sqlite、wasi-llm — Spin がホストとして提供する P2 インターフェース。
- Spin SDK — Rust、Go、JS/TS、Python、.NET、Java。
最も単純な HTTP コンポーネントのマニフェスト:
spin_manifest_version = 2
[application]
name = "hello-spin"
version = "0.1.0"
[[trigger.http]]
route = "/hello/..."
component = "hello"
[component.hello]
source = "target/wasm32-wasip2/release/hello.wasm"
allowed_outbound_hosts = ["https://api.example.com"]
key_value_stores = ["default"]
sqlite_databases = ["default"]
[component.hello.build]
command = "cargo build --target wasm32-wasip2 --release"
watch = ["src/**/*.rs", "Cargo.toml"]
Spin は単一バイナリ(spin up)としてローカルで動き、Fermyon Cloud または Fermyon Platform for Kubernetes(spin-operator)経由でデプロイする。一言で言えば「WASM ネイティブのマイクロサービス運用体系」だ。
2026 年に入って Spin は LangChain / LlamaIndex 風の AI ワークフロー(spin-llm)と統合し、エッジ AI サーバーのカテゴリへ広がった。
第 8 章 · wasmCloud — 分散アクターモデルの上の WASM
wasmCloud は CNCF Incubating プロジェクトで、「WASM コンポーネント + アクターモデル + NATS メッセージング」を一式で提供する。中核の発想:
- すべてのビジネスロジックは コンポーネント(アクター) だ。コンポーネントは WIT インターフェースだけを知る。
- 外部システム(DB・HTTP・キーバリュー・blob)は プロバイダ(capability provider) が担当する。
- 両者の間を lattice(NATS の上に作る仮想ネットワーク)がルーティングする。
これはまさに依存性反転だ。コンポーネントは「Redis を呼ぶ」のではなく「wasi:keyvalue/store を呼ぶ」。その実体が Redis なのか NATS KV なのか Postgres なのかは、運用者が wadm(wasmCloud Application Deployment Manager)上でバインドする。
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: hello-wasmcloud
spec:
components:
- name: hello
type: component
properties:
image: ghcr.io/example/hello:0.1.0
traits:
- type: spreadscaler
properties:
instances: 5
- type: link
properties:
target: redis-kv
namespace: wasi
package: keyvalue
interfaces: ["store"]
- name: redis-kv
type: capability
properties:
image: ghcr.io/wasmcloud/redis-kv:0.10.0
複数のクラウド・エッジ・オンプレに同じ lattice を伸ばせる点が wasmCloud の強みだ。Adobe・BMW・Bosch がカンファレンス事例で繰り返し登場する。
第 9 章 · Lunatic — Erlang / Elixir 由来の WASM ランタイム
Lunatic は BEAM(Erlang VM)のアクター・スーパーバイザツリー・プリエンプティブスケジューリングというアイデアを WASM に移したランタイムだ。Rust で書かれ、Wasmtime をコアに利用する。
- 数十万の軽量プロセス を一ノードで起動できる。
- OTP スタイルのスーパーバイザ が子プロセスを監視。
- メッセージパッシング のみで通信。共有メモリなし。
- distributed mode でノード間メッセージング。
特化領域は次のとおり。
- 並行性が中核となるゲームサーバー、チャット、コラボレーションツール。
- 長時間生存するワークフローエンジン。
- 小さな単位で隔離されるべきマルチテナント SaaS。
Spin が「HTTP ハンドラの束」に近いとすれば、Lunatic は「WASM 版 BEAM」だ。両者は競合ではなく、異なるユースケースに住んでいる。
第 10 章 · Extism — ホストアプリに WASM プラグインを埋め込む標準
Extism は「自分のアプリを WASM プラグインで拡張したい」というたった一つの問題に集中する。Dylibso が OSS で開発している。
- ホスト SDK: C、Rust、Go、JavaScript(Node・ブラウザ)、Python、Ruby、PHP、.NET、Java、Zig、Haskell、Elixir、OCaml。
- プラグイン SDK(PDK): Rust、Go、AssemblyScript、JS、Zig、C、Haskell。
- インターフェースは WASM 関数 + メモリ + ホスト関数。Component Model より単純な ABI。
代表的なシナリオ:
- データベース / キューのユーザー定義関数 — Cloudflare D1、Materialize、Tessera のようなシステムでユーザーコードを安全に実行。
- CMS / SaaS の拡張点 — Sanity、GitHub Actions、社内ワークフローエンジン。
- CLI ツールのプラグイン —
awscli、kubectl、terraformが外部コードを安全に組み込む。
Extism は Component Model の汎用性を一部譲って、ホスト統合の単純さ を取った。2026 年時点で Extism 1.x が安定版であり、OCI レジストリからプラグインを取得する extism call oci://... フローが標準化している。
第 11 章 · JCO と StarlingMonkey — JavaScript もコンポーネントになる
JCO(JavaScript Component Object)は Bytecode Alliance が作った JavaScript ↔ Component 変換ツールだ。2026 年現在 jco 1.x が安定版である。
主な機能:
jco componentize app.js --wit ./wit -o app.wasm— JavaScript を StarlingMonkey(SpiderMonkey 由来の組み込み JS エンジン)で梱包し、単一コンポーネント .wasm を生成。jco transpile component.wasm -o ./out— コンポーネントを Node.js / ブラウザから import 可能な ES モジュールへ変換。jco run app.wasm— Node 上で P2 コンポーネントを直接実行。
StarlingMonkey は Mozilla の SpiderMonkey を組み込み形態に切り出したもので、Cloudflare workerd に続く次世代の JS-on-WASM ランタイムだ。Fastly Compute と Fermyon Spin が JS コンポーネントのランタイムとして StarlingMonkey を採用している。
JCO の真価は TypeScript 型の自動生成 にある。WIT ファイルから .d.ts を生成し、呼び出し側が全関数・全リソースに型安全にアクセスできる。
// app.js — jco componentize の入力
import { now } from 'wasi:clocks/wall-clock@0.2.0';
import { log } from 'wasi:logging/logging@0.2.0';
export const api = {
greet(name) {
const { seconds } = now();
log('info', 'greeter', `now=${seconds}`);
return `Hello, ${name}! It is now ${seconds}.`;
},
};
このファイル一枚が jco を通せば、どのホスト(Wasmtime、Spin、wasmCloud、Cloudflare Workers)でも実行可能なコンポーネントになる。
第 12 章 · ポリグロットなコンパイル経路 — Rust、Go、C/C++、AssemblyScript、Python、Java、.NET
各言語の 2026 年標準コンパイル経路を短く整理する。
| 言語 | ツール | ターゲット | 備考 |
|---|---|---|---|
| Rust | rustc + cargo-component | wasm32-wasip2 | 一級対応、最短経路 |
| C/C++ | wasi-sdk(clang 19+) | wasm32-wasip2 | wit-bindgen-c でコンポーネント化 |
| Go | TinyGo 0.34+ | wasip2 | 標準 Go も wasip1 対応、wasip2 は TinyGo が速い |
| AssemblyScript | asc 0.27+ | wasm32 | TS ライクな構文、小さなバイナリ |
| JavaScript | jco + StarlingMonkey | component | 第 11 章参照 |
| Python | componentize-py | component | CPython を WASM に梱包 |
| Java | TeaVM、CheerpJ、Spasm | wasm32-gc | JVM バイトコードを WASM-GC へ |
| C# / .NET | wasi-experimental + NativeAOT | wasi | .NET 9 で WASI P2 正式化が進行 |
| Ruby | ruby.wasm | wasi | Ruby 3.3+ 公式 WASM ビルド |
| Zig | zig build -target wasm32-wasi | wasi | コンポーネント化は wasm-tools |
特に Python・Java・.NET がコンポーネント化できるようになったのが 2024-2025 年の大きな変化だ。「C/Rust だけの領域」という認識はもう過去のものだ。
第 13 章 · WIT と wit-bindgen — インターフェース・ファースト開発
Component Model の本当の働き方は「まず WIT を書き、次に実装言語を選ぶ」という流れだ。
wit-bindgen は WIT を読んで各言語のバインディングを生成する。Rust 例:
wit_bindgen::generate!({
world: "greeter",
path: "./wit",
});
use exports::example::greeter::api::Guest;
struct Component;
impl Guest for Component {
fn greet(name: String) -> String {
format!("Hello, {name} from Rust WASM!")
}
}
export!(Component);
ビルドは wasm-tools でコンポーネント化する。
cargo build --target wasm32-wasip2 --release
wasm-tools component new \
target/wasm32-wasip2/release/greeter.wasm \
-o greeter.component.wasm
wasm-tools validate greeter.component.wasm
生成された greeter.component.wasm は Wasmtime、Spin、jco、wasmCloud のどこで動かしても同一だ。これが Component Model の約束だ。
第 14 章 · Cloudflare Workers と WASM — V8 isolate の上のモジュール
Cloudflare Workers は V8 isolate を基本の隔離単位としつつ、WASM を一級モジュールとしてサポートする。
wrangler.tomlの[[rules]]+type = "CompiledWasm"で WASM バインディング。- JS Worker が WASM モジュールの export を直接呼ぶ。
- メモリ 32MB、CPU 50ms(無料)/ 30 秒(有料)の制限。
- 2025 年に WASI Preview 2 コンポーネントの直接実行 がベータで登場。以前は JS shim が必要だった。
典型的な Rust → WASM → Workers の流れ:
cargo install wasm-pack
wasm-pack build --target web
wrangler deploy
Workers は強力だが、Component Model のあらゆる側面(任意のホスト import など)を扱うわけではない。Cloudflare は自前のビルトインバインディング(KV、R2、D1、Queues、AI、Durable Objects)を提供する形を取っている。
第 15 章 · Fastly Compute@Edge — WASM ファーストなエッジの原型
Fastly Compute@Edge は最初から WASM(Wasmtime ベース)の上に作られたエッジプラットフォームだ。V8 isolate を経由せず、直接 WASM インスタンスを起動する。
- pre-instantiation のおかげでコールドスタート 1ms 未満。
- Rust、JS、Go(TinyGo)、AssemblyScript の一級 SDK。
- ESI(Edge Side Includes)、KV Store、Config Store、Object Store、Secret Store。
- 2025 年に P2 コンポーネントを正式採用、2026 年には jco で作った JS コンポーネントを直接実行。
Fastly の強みは ロギング・リアルタイムメトリクスの充実 と SOC2 / PCI / HIPAA の認証範囲だ。メディア・EC・金融サービスが Fastly Compute に多く住んでいる。
第 16 章 · AWS Lambda Web Adapter と WASM — Lambda 上でコンポーネントを動かす
AWS Lambda は 2026 年現在、公式の WASM ランタイムを持たない。代わりに二つの迂回路が標準だ。
- AWS Lambda Web Adapter — Lambda のコンテナイメージ内に Wasmtime を組み込み、コンポーネントを実行する。
awslabs/aws-lambda-web-adapterGitHub リポジトリ。 - Fermyon Spin on Lambda — Spin コンポーネントを Lambda Adapter でラップしてデプロイ。
Lambda の 350ms 級コールドスタートと Wasmtime のマイクロ秒級コールドスタートの差は、そのままユーザーの負担になる。だから本気の WASM エッジは Fastly・Cloudflare・Fermyon Cloud・Cosmonic・Wasmer Edge へ流れることが多い。
ただし AWS は Bedrock のユーザー定義関数 で WASM を受け入れる方向性を 2025 年後半に発表した。今後 1-2 年で Lambda + WASM が一級になる可能性は高い。
第 17 章 · Docker WASM と containerd-wasm-shims — コンテナなしの WASM
Docker Desktop は 4.15+ で WASM ワークロードを公式ベータとしてサポートし、2025 年に GA を迎えた。実装は containerd-shim-wasmtime、containerd-shim-wasmedge、containerd-shim-wasmer、containerd-shim-spin の四種類だ。
OCI イメージの中に WASM バイナリがあれば、ノードで --runtime=io.containerd.wasmedge.v1 のようなフラグ一行で WASM が走る。コンテナランタイムがコンテナではなく WASM インスタンスを起動するという意味だ。
Kubernetes でも RuntimeClass で同じことが可能だ。結果として一台のノードでコンテナと WASM が共存し、ワークロードの種類に応じてスケジューラが自動的に振り分ける。
第 18 章 · ケーパビリティ型セキュリティ — なぜ WASM はコンテナより狭い信頼境界なのか
コンテナの隔離は Linux カーネルの namespace + cgroup + seccomp + AppArmor の組み合わせだ。強力だが、信頼がカーネル一点に依存する。CVE 一件で隔離全体が崩れうる。
WASM の隔離は違う。
- メモリ は linear memory 一塊。モジュールは自分の割り当て領域だけを見る。
- 関数呼び出し は import テーブル経由のみ。未知のホスト関数は呼べない。
- システムコール という概念自体がない。外との接点は WASI import のみ。
- 決定性 — 入力と imports が同じなら出力も同じ。キャッシュ・証明・再現が容易。
このモデルがコンテナよりも 狭い信頼境界 を生む。コンテナは「基本は全部あげる、そこから引け」、WASM は「基本は何もあげない、そこから足せ」のモデルだ。
エンタープライズのセキュリティチームにとって、この差は非常に大きい。マルチテナント SaaS、ユーザーコード実行(Cloudflare Workers、Replit、Modal)、信頼できないプラグイン — どのシナリオでも WASM はコンテナより安全な答えだ。
第 19 章 · 性能 — コールドスタート、JIT、AOT、そして pre-instantiation
WASM の性能を一行で答えるのは難しい。三つの段階を分けよう。
- コンパイル — .wasm バイトコードをネイティブコードへ変換。JIT(Wasmtime のデフォルト)vs AOT(WasmEdge・Wasmer LLVM・Wasmtime
--cache)。 - インスタンス化 — コンパイル済みモジュールにメモリ・テーブル・グローバルを束ねて実行可能インスタンスを作る。
- 実行 — 実際の関数呼び出し。
コールドスタートの肝は pre-instantiation と pooling だ。
- Wasmtime の
--allow-precompiled+ .cwasm でコンパイル段階を省略。 - Pooling allocator でインスタンスをプールから再利用 → 数十マイクロ秒で起動。
- Fastly Compute は全 .wasm をデータプレーンに事前ロードし、リクエストごとにインスタンスだけ作る。
実行性能は LLVM バックエンドでネイティブ比 70-95%。SIMD・threads・tail call が効くワークロード(画像処理・暗号・ML 推論)は 90% 超もよくある。
コールドスタート比較(2026 年 5 月時点の報告値):
| ランタイム | コールドスタート |
|---|---|
| AWS Lambda(Node) | 約 350ms |
| Cloudflare Workers(JS isolate) | 約 5ms |
| Fastly Compute@Edge(WASM) | 1ms 未満 |
| Wasmtime + pooling | 約 50µs |
| WasmEdge AOT | 約 30µs |
第 20 章 · ポリグロットデモ — Rust でコンポーネント、JS から呼び出し
この章一つで Component Model の実用を見る。WIT は第 3 章の greeter をそのまま使う。
Rust 実装(src/lib.rs):
wit_bindgen::generate!({ world: "greeter", path: "./wit" });
use exports::example::greeter::api::{Counter, Guest, GuestCounter};
use std::cell::Cell;
struct Component;
impl Guest for Component {
fn greet(name: String) -> String {
format!("Hi, {name}!")
}
type Counter = CounterImpl;
}
struct CounterImpl(Cell<u64>);
impl GuestCounter for CounterImpl {
fn new() -> Self { Self(Cell::new(0)) }
fn increment(&self) { self.0.set(self.0.get() + 1); }
fn get(&self) -> u64 { self.0.get() }
}
export!(Component);
ビルドと JS 側からの呼び出し:
cargo build --target wasm32-wasip2 --release
wasm-tools component new target/wasm32-wasip2/release/greeter.wasm -o greeter.wasm
jco transpile greeter.wasm -o out --name greeter
node -e "import('./out/greeter.js').then(m => { const c = new m.api.Counter(); c.increment(); c.increment(); console.log(m.api.greet('JS'), c.get()); })"
同じ .wasm を Spin・wasmCloud・Wasmtime CLI でもそのまま呼べる。ポリグロットの約束が紙の上ではなく実行可能なコードの上にあるという点が肝心だ。
第 21 章 · WASM と AI — LLM 推論と ggml on WASM
2024 年から本格化した流れだ。
- WasmEdge + llama.cpp(ggml) — Llama 3 8B を単一の .wasm から推論。1MB の .wasm が GPU / CPU バックエンドを自動選択する。
- wasi-nn — WASI の ML インターフェース。PyTorch、ONNX、OpenVINO、TFLite を統一インターフェースで呼ぶ。
- Burn-wasm、Candle-wasm — Rust ネイティブの ML フレームワークを WASM へ。
- Cloudflare Workers AI + WASM 後処理 — モデルは Workers AI が回し、応答の後処理を WASM コンポーネントが担う。
WasmEdge ggml の魅力は モデルを OS / ハードウェア非依存に配布 できる点だ。Linux x86_64、macOS arm64、Raspberry Pi、AWS Graviton に同じ .wasm を投げ込めば、その場で推論が始まる。組み込み・エッジ AI のゲームチェンジャーだ。
第 22 章 · LINE / NHN Cloud / Cybozu — 韓国・日本の WASM 事例
韓国と日本の導入はインフラ・コンテンツ系企業が先導している。
- LINE / LY — メッセージングバックエンドの一部サイドカーで WASM プラグインを評価中(2024 年 Tech-Verse 発表)。
- NHN Cloud — 自社エッジ関数のベータで WasmEdge ベースのランタイムを採用。Toast クラウドのエッジサービスでユーザーコード実行の隔離に活用。
- Naver Cloud — Naver Search / Smart Store でユーザー定義の検索後処理に WASM プラグインを評価(2025 年 DAN 発表)。
- Cybozu — kintone のプラグインモデルを Extism ベースに再設計する実験を 2024-2025 年に進行。
- Sansan — 名刺データ処理パイプラインの一部を WASM コンポーネントへ移行した事例を自社ブログで公開。
- DeNA — モバイルゲームのクライアントとサーバー共通ロジックを Rust → WASM で共有。
- NTT Communications — Smart Data Platform のノード側処理の一部を WASM へ。
事例の共通点は コンテナでは答えが出にくいマルチテナント・プラグイン・エッジ隔離 の問題に WASM が入ってきたことだ。
第 23 章 · 運用 — 観測、デバッグ、デプロイ
WASM が運用水準に到達した分、観測ツールも整ってきた。
- wasmtime --profile=guest、--jitdump — ゲストプロファイリング。Linux perf と統合。
- WASI Logging(wasi:logging/logging) — 構造化ログをホストが受け取り OpenTelemetry へ転送。
- wasi:observe(実験的) — トレース / スパンをコンポーネントからホストへ流す仕様。
- Spin Trace + Fermyon Cloud Logs — Spin ワークロードの分散トレース。
- wasmCloud + NATS Telemetry — lattice 内の呼び出しグラフを NATS メタデータでキャプチャ。
デバッグはまだ進化途中だが、2025 年に入って DWARF デバッグ情報を保持した .wasm、wasmtime の --gdb モード、Chrome DevTools の WASM デバッガが組み合わさり、実務でも使える水準になった。AssemblyScript と Rust は DWARF 出力が良く、Go はまだ弱点が残る。
デプロイは OCI レジストリ(ghcr.io、docker.io)にコンポーネント .wasm を push し、Spin / wasmCloud / Knative が pull する GitOps フローが標準だ。
第 24 章 · 未来 — wasi-preview3、async / streams、wasi-gpu、wasi-threads
2026 年半ば時点で可視化されている次の一歩。
- WASI Preview 3 — async / await を一級 ABI として受け入れる仕様。2026 年後半に候補化の可能性。
- wasi:io/streams の一般化 — すべての IO が非同期 stream に統一される。
- wasi:gpu(WebGPU on WASI) — GPU コンピュートをケーパビリティに。ML 推論・グラフィクスの決定的仕様。
- wasi-threads — マルチスレッドコンポーネント。現状は Wasmtime の実験機能。
- コンポーネント ↔ Linux プロセスモデル — コンポーネントがホストプロセス一つに 1:1 対応する標準化。
- Bytecode Alliance 配下のワーキンググループが安定レベル(Phase 4)へ押し上げ中。
WASM はもはや単一仕様ではなく、IETF / W3C 風にインターフェースをガバナンスする多層エコシステムになった。
第 25 章 · 意思決定ツリー — 自分のワークロードにどのランタイムを選ぶか
最後に実用ガイド。
| ワークロード | 推奨 |
|---|---|
| エッジの HTTP API | Fastly Compute@Edge、Cloudflare Workers、Spin + Fermyon Cloud |
| 自社 K8s クラスタのサイドカー | WasmEdge + RuntimeClass、Spin + spin-operator |
| 分散マルチクラウドのマイクロサービス | wasmCloud + NATS |
| AI 推論(エッジ / 組み込み) | WasmEdge ggml、Wasmer + Burn |
| ホストアプリのプラグイン | Extism |
| 並行性中心のサービス | Lunatic |
| ユーザーコード実行(マルチテナント) | Wasmtime + epoch interruption + pooling |
| Lambda 上に載せる | Lambda Web Adapter + Wasmtime |
選択の四軸:
- 信頼境界 — ユーザーのコードが入るか。入るなら WASM。
- コールドスタート — ms 未満が必要か。必要なら Fastly・Spin・WasmEdge AOT。
- 言語多様性 — ポリグロットか。なら Component Model 一級対応(Wasmtime / Spin / wasmCloud)。
- 運用モデル — K8s の標準に乗せたいか、PaaS に任せたいか。
この四問に答えれば、ツールはほぼ自動的に決まる。
第 26 章 · まとめ — 「Docker の次」ではなく「Docker の上の強い隔離」
WASM の未来をめぐって「コンテナを置き換えるのか」という問いが繰り返される。2026 年の現場の答えは明快だ — 置き換えではなく補完 だ。
- コンテナは依然として OS 単位の隔離に最適だ。フルスタック・OS 依存・巨大なワークロードはコンテナに残る。
- WASM は 関数・サービス単位の隔離 に最適だ。信頼できないコード、マルチテナントプラグイン、ポリグロット ABI、エッジが WASM の領域だ。
両者は K8s ノード上に同居する。ワークロードの種類に応じて RuntimeClass が振り分ける。Solomon Hykes のツイートは「WASM が Docker を置き換えていたはずだ」ではなく 「WASM は Docker が解決してきた問題の一部を別のやり方で解ける」 という、より微妙な真実に近い。
本稿は 26 章でその「別のやり方」の全貌を描いた。WIT 一行を書くところから始まり — その一行が Rust・Go・JS・Python で実装され、Wasmtime・Spin・wasmCloud・Fastly・Cloudflare で同じ形で実行される — 2026 年の風景はそれらすべてが同時に可能になった時代だ。
「自分のコードはどこで、どんな権限で動くのか、そして誰がそれを組み立てるのか」。この二つの問いに明確に答えられるなら、私たちはいまやその答えを同じ .wasm 一つに収めて持ち歩ける。
References
- WebAssembly 公式 — https://webassembly.org/
- WASI 公式 — https://wasi.dev/
- Component Model 仕様 — https://component-model.bytecodealliance.org/
- Bytecode Alliance — https://bytecodealliance.org/
- Wasmtime ドキュメント — https://docs.wasmtime.dev/
- Wasmer ドキュメント — https://docs.wasmer.io/
- WasmEdge ドキュメント — https://wasmedge.org/docs/
- Fermyon Spin ドキュメント — https://developer.fermyon.com/spin
- wasmCloud ドキュメント — https://wasmcloud.com/docs
- Extism ドキュメント — https://extism.org/docs/overview
- JCO(JavaScript Component) — https://bytecodealliance.github.io/jco/
- wit-bindgen — https://github.com/bytecodealliance/wit-bindgen
- wasm-tools — https://github.com/bytecodealliance/wasm-tools
- Cloudflare Workers + WASM — https://developers.cloudflare.com/workers/runtime-apis/webassembly/
- Fastly Compute — https://www.fastly.com/documentation/guides/compute/
- AWS Lambda Web Adapter — https://github.com/awslabs/aws-lambda-web-adapter
- Docker WASM — https://docs.docker.com/desktop/wasm/
- Lunatic — https://lunatic.solutions/
- WASIX — https://wasix.org/
- StarlingMonkey — https://github.com/bytecodealliance/StarlingMonkey
- componentize-py — https://github.com/bytecodealliance/componentize-py
- containerd-wasm-shims — https://github.com/deislabs/containerd-wasm-shims
- Spin Operator(Kubernetes) — https://github.com/spinkube/spin-operator
- WasmEdge ggml plugin — https://github.com/second-state/WasmEdge-WASINN-examples
- Solomon Hykes tweet on WASM — https://twitter.com/solomonstre/status/1111004913222324225