😮

BunはWasmファイルを直接実行できる

に公開

WebAssembly Advent Calendar 2025 6日目の記事です。

https://qiita.com/advent-calendar/2025/wasm

はじめに

最近、Anthropicに買収されたことで話題のJavaScriptランタイムのBunですが、Wasm(正確に言えばWASI)ファイルを直接実行する機能があります。

bun hello.wasm

この機能はBun v0.5.2で追加されており、ドキュメントにも書かれていないので知ってる人も少ないのではないでしょうか?

https://bun.com/blog/bun-v0.5.2#run-webassembly-files-with-bun-run

https://github.com/oven-sh/bun/pull/1929

今回は簡単な実行例と共に内部実装を確認してみたいと思います。

実行例

Bunは大部分がZigで書かれているので、今回の例もZigを使ってWasmを作り実行してみましょう。次の記事を参考にWasmをビルドして実行してみます。

https://zenn.dev/moton03/articles/b9650dfce15883

hello.zig
const std = @import("std");

pub fn main() void {
    std.debug.print("Hello, World!\n", .{});
}

ビルドコマンド

zig build-exe hello.zig -target wasm32-wasi

生成されたhello.wasmをbunで実行すると、

$ bun hello.wasm
Hello, World!

となり、実行できることが確認できると思います。

内部的な仕組み

コマンド実行時に.wasm拡張子を検出すると、内部に持っているwasi-runner.jsを代わりに実行します。wasi-runner.jsでは、node:wasiモジュールを使用してWASIインスタンスを生成して実行しているという、シンプルな仕組みで動いています。

https://github.com/oven-sh/bun/blob/4d60b6f69d2ade569a5f231f87dc5ff56dea7196/src/js/wasi-runner.js

他のJSランタイムの対応状況

現状直接Wasmを実行できる対応を行っているのはBunだけのようです。
Denoも対応を検討しているようですが、node:wasiがまだ実装されていないため対応されていないようです。

https://github.com/denoland/deno/issues/22448

Node.jsでは特に情報は見つかりませんでした。

Discussion