Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Wasmのエコシステムを使った ツール作成方法

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for asuka asuka
October 11, 2025

Wasmのエコシステムを使った ツール作成方法

Avatar for asuka

asuka

October 11, 2025
Tweet

More Decks by asuka

Other Decks in Technology

Transcript

  1. WHOAMI 2 name = asuka fav = Wasm [org] name

    = 株式会社モニクル role = SWE [sns] X = @a_skua GitHub = @a-skua Bluesky = @askua.dev
  2. 3 Go Conference 2025 Pure Goで体験するWasmの未来 - Speaker Deck •

    Wasmを使って安全にツールを実行できる • コンテナレジストリを経由してWasmを配布できる
  3. GOOS=wasip2 GOARCH=wasm 6 Go 1.21〜 • GOOSwasip1 GOARCH=wasm tinygoでは先行してWASI 0.2をサポートしている

    • GOOSwasip2 GOARCH=wasm WASI - Wasmを汎用バイナリとして利用するためのAPI仕様 WASI 0.1 (=wasip1 - POSIX APIを参考に策定 / ネットワークは未サポート WASI 0.2 (=wasip2 - Wasmコンポーネントモデルをベースに再設計 2018年 8月 G o 1.11 リ リ ー ス W asm サ ポ ー ト 2019年 W A SI 0.1 リ リ ー ス 2023年 8月 G o 1.21 リ リ ー ス W A SI 0.1 サ ポ ー ト 2024年 1月 W A SI 0.2 リ リ ー ス 2024年 8月 W A SI 0.2.1 リ リ ー ス W asm O C I A rtifact layout 2025年 W A SI 0.3 リ リ ー ス ? 2025年 2月 G o 1.24 リ リ ー ス W A SI 0.1 リ ア ク タ ー モ ジ ュ ー ル サ ポ ー ト
  4. GOOS=wasip2 GOARCH=wasm 7 Go 1.21〜 • GOOSwasip1 GOARCH=wasm tinygoでは先行してWASI 0.2をサポートしている

    • GOOSwasip2 GOARCH=wasm WASI - Wasmを汎用バイナリとして利用するためのAPI仕様 WASI 0.1 (=wasip1 - POSIX APIを参考に策定 / ネットワークは未サポート WASI 0.2 (=wasip2 - Wasmコンポーネントモデルをベースに再設計 2018年 8月 G o 1.11 リ リ ー ス W asm サ ポ ー ト 2019年 W A SI 0.1 リ リ ー ス 2023年 8月 G o 1.21 リ リ ー ス W A SI 0.1 サ ポ ー ト 2024年 1月 W A SI 0.2 リ リ ー ス 2024年 8月 W A SI 0.2.1 リ リ ー ス W asm O C I A rtifact layout 2025年 W A SI 0.3 リ リ ー ス ? 2025年 2月 G o 1.24 リ リ ー ス W A SI 0.1 リ ア ク タ ー モ ジ ュ ー ル サ ポ ー ト e.g.$ cat hello.go package main import ( "fmt" ) func main() { fmt.Println("Hello, 世界!") } e.g.$ GOOS=wasip2 GOARCH=wasm \ > tinygo build -o hello.wasm hello.go e.g.$ wasmtime run hello.wasm Hello, 世界!
  5. GOOS=wasip2 GOARCH=wasm 8 WASI 0.2の特徴 • コンポーネントモデルの採用 • ネットワーク対応 WASI

    - Wasmを汎用バイナリとして利用するためのAPI仕様 WASI 0.1 (=wasip1 - POSIX APIを参考に策定 / ネットワークは未サポート WASI 0.2 (=wasip2 - Wasmコンポーネントモデルをベースに再設計 2018年 8月 G o 1.11 リ リ ー ス W asm サ ポ ー ト 2019年 W A SI 0.1 リ リ ー ス 2023年 8月 G o 1.21 リ リ ー ス W A SI 0.1 サ ポ ー ト 2024年 1月 W A SI 0.2 リ リ ー ス 2024年 8月 W A SI 0.2.1 リ リ ー ス W asm O C I A rtifact layout 2025年 W A SI 0.3 リ リ ー ス ? 2025年 2月 G o 1.24 リ リ ー ス W A SI 0.1 リ ア ク タ ー モ ジ ュ ー ル サ ポ ー ト
  6. コンポーネントモデルとWIT コンポーネントモデル • 複数のWasmモジュールを1つのコンポーネントとしてまとめるための仕様 • WITIDLを使ってインターフェースを定義 (like Protocol Buffers) 10

    interface calc { eval: func(exp: string) -> result<s32, error>; } world a { import calc; export wasi:cli/run; } world b { export calc; } e.g. Rustで実装 e.g. Goで実装
  7. コンポーネントモデルとWIT コンポーネントモデル • 複数のWasmモジュールを1つのコンポーネントとしてまとめるための仕様 • WITIDLを使ってインターフェースを定義 (like Protocol Buffers) 11

    interface calc { eval: func(exp: string) -> result<s32, error>; } world a { import calc; export wasi:cli/run; } world b { export calc; } e.g. Rustで実装 e.g. Goで実装 e.g.$ cat foo.go package main import ( "go.bytecodealliance.org/cm" "example.com/component/gen/example/root/calc" ) func init() { calc.Exports.Eval = func(exp string) cm.Result[string, int32, string] { panic("TODO") } } func main() {} ptrとlenではなく,stringを扱えるのも特徴の1つ
  8. ネットワーク 13 WASI 0.2の特徴 • ネットワーク対応 • コンポーネントモデルの採用 WASI -

    Wasmを汎用バイナリとして利用するためのAPI仕様 WASI 0.1 (=wasip1 - POSIX APIを参考に策定 / ネットワークは未サポート WASI 0.2 (=wasip2 - Wasmコンポーネントモデルをベースに再設計 2018年 8月 G o 1.11 リ リ ー ス W asm サ ポ ー ト 2019年 W A SI 0.1 リ リ ー ス 2023年 8月 G o 1.21 リ リ ー ス W A SI 0.1 サ ポ ー ト 2024年 1月 W A SI 0.2 リ リ ー ス 2024年 8月 W A SI 0.2.1 リ リ ー ス W asm O C I A rtifact layout 2025年 W A SI 0.3 リ リ ー ス ? 2025年 2月 G o 1.24 リ リ ー ス W A SI 0.1 リ ア ク タ ー モ ジ ュ ー ル サ ポ ー ト e.g.$ cat http-server.go package main import ( "fmt" "net/http" ) func handle(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, 世界!") } func main() { http.HandleFunc("/", handle) fmt.Println("Starting server on :8080") if err := http.ListenAndServe(":8080", nil); err != nil { fmt.Println("Error starting server:", err) } } 標準パッケージはネットワークをサポートしていない GOOS=wasip2 GOARCH=wasmだけだと動かない
  9. ネットワーク 14 WASI 0.2の特徴 • コンポーネントモデルの採用 • ネットワーク対応 WASI -

    Wasmを汎用バイナリとして利用するためのAPI仕様 WASI 0.1 (=wasip1 - POSIX APIを参考に策定 / ネットワークは未サポート WASI 0.2 (=wasip2 - Wasmコンポーネントモデルをベースに再設計 2018年 8月 G o 1.11 リ リ ー ス W asm サ ポ ー ト 2019年 W A SI 0.1 リ リ ー ス 2023年 8月 G o 1.21 リ リ ー ス W A SI 0.1 サ ポ ー ト 2024年 1月 W A SI 0.2 リ リ ー ス 2024年 8月 W A SI 0.2.1 リ リ ー ス W asm O C I A rtifact layout 2025年 W A SI 0.3 リ リ ー ス ? 2025年 2月 G o 1.24 リ リ ー ス W A SI 0.1 リ ア ク タ ー モ ジ ュ ー ル サ ポ ー ト
  10. ネットワーク 15 WASI 0.2の特徴 • コンポーネントモデルの採用 • ネットワーク対応 WASI -

    Wasmを汎用バイナリとして利用するためのAPI仕様 WASI 0.1 (=wasip1 - POSIX APIを参考に策定 / ネットワークは未サポート WASI 0.2 (=wasip2 - Wasmコンポーネントモデルをベースに再設計 2018年 8月 G o 1.11 リ リ ー ス W asm サ ポ ー ト 2019年 W A SI 0.1 リ リ ー ス 2023年 8月 G o 1.21 リ リ ー ス W A SI 0.1 サ ポ ー ト 2024年 1月 W A SI 0.2 リ リ ー ス 2024年 8月 W A SI 0.2.1 リ リ ー ス W asm O C I A rtifact layout 2025年 W A SI 0.3 リ リ ー ス ? 2025年 2月 G o 1.24 リ リ ー ス W A SI 0.1 リ ア ク タ ー モ ジ ュ ー ル サ ポ ー ト 標準パッケージを使えない →wasi:httpのWIT使ってインターフェースを実装する
  11. wasi:http/proxyを実装する 17 world proxy { import ...; export incoming-handler; }

    wasi:http/proxyの定義 WASI 0.2の2つのエントリーポイント • wasi:cli/command → CLIコマンドの起動 • wasi:http/proxy → HTTPサーバーの起動
  12. wasi:http/proxyを実装する 18 world http-proxy { include wasi:cli/[email protected]; include wasi:http/[email protected]; }

    wit/world.wit e.g.$ wkg wit build -o world.wasm wit/world.wit e.g.$ wit-bindgen-go generate \ > --world http-proxy \ > --out internal/gen world.wasm
  13. • wkg ◦ WITをWasmに変換 ◦ wit/world.wit → world.wasm • wit-bindgen-go

    ◦ WasmからGoのコードを生成 ◦ world.wasm → internal/gen wasi:http/proxyを実装する 19 e.g.$ wkg wit build -o world.wasm wit/world.wit e.g.$ wit-bindgen-go generate \ > --world http-proxy \ > --out internal/gen world.wasm
  14. wasi:http/proxyを実装する 20 e.g.$ wkg wit build -o world.wasm wit/world.wit e.g.$

    wit-bindgen-go generate \ > --world http-proxy \ > --out internal/gen world.wasm ./internal/gen/ ./wit/world.wit import ( gohttp "net/http" "github.com/a-skua/go-wasi/internal/gen/wasi/http/incoming-handler" "github.com/a-skua/go-wasi/internal/gen/wasi/http/types" ) var Handler gohttp.Handler func init() { incominghandler.Exports.Handle = handle } func handle(in types.IncomingRequest, out types.ResponseOutparam) { r, _ := http.ParseRequest(in) // TODO: err handle w := http.NewResponseWriter(out) defer w.Flush() Handler.ServeHTTP(w, r) } http.Handler func (w http.ResponseWriter, r *http.Request) error wasi:http/incoming-handler func(request: incoming-request, response-out: response-outparam) 生成されたコード
  15. wasi:http/proxyを実装する 21 package main import ( "fmt" "net/http" "github.com/a-skua/go-wasi/http/proxy" )

    func main() {} func init() { proxy.Handler = http.HandlerFunc(httpHandler) } func httpHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, 世界!\n") } e.g.$ wasmtime serve S cli http-proxy.wasm Serving HTTP on http://0.0.0.08080/ e.g.$ curl http://localhost:8080 Hello, 世界! e.g.$ tinygo build --target=wasip2 --no-debug \ > --wit-package world.wasm --wit-world proxy \ > -o proxy.wasm proxy.go
  16. • Pure Goで体験するWasmの未来 - Speaker Deck • Wasm OCI Artifact

    layout | CNCF TAG Runtime • GitHub - bytecodealliance/go-modules • GitHub - bytecodealliance/wasm-pkg-tools • Repository for design and specification of the Component Model リンク 26