🥖

【Bun】新しいJavaScriptランタイムについてふわっとまとめた

2022/07/12に公開

JavaScriptランタイムと言えばnode
nodeの代替としてdenoがありますが、新たにbunというものを知ったのでふわっとまとめてみました。次のリンクは、Bunを知るきっかけとなったものです。
https://news.ycombinator.com/item?id=31993429
トップのコメントを一部抜粋(DeepL翻訳)

私が興奮していることのひとつは、bun install です。

Linuxでは、シンプルなNext.jsアプリの依存関係を、現在利用できる他のnpmクライアントよりも20倍ほど速くインストールします。

Bunとは

「速くて All in One な Javascript ランタイム」
https://bun.sh/
内容を見ていく前に、Bunへの注目度がわかるグラフをご覧ください。

7月6日からほぼ垂直にStarを獲得しており、7月11日までの五日間で約20倍になっています。すごい。
ここからは私が気になった内容をピックアップして紹介していきます。

All in One

BunはAll in Oneなツールです。
バンドルトランスパイラパッケージマネージャなどが最初からbunに含まれています。
nodeで言うところの、webpacknpmbun一つで完結しているということです。
また、bunのパッケージマネージャはnpm互換なのでnpmを使うようにbunを使うことができます。

bun npm
bun install npm install
bun remove react npm uninstall react
bun add preact npm install preact
bun run clean npm run clean

その他にもWeb開発で必要になることが多い機能が含まれています。

  • fetch,WebSocket,ReadableStream
  • .envから環境変数を自動で読み込みます。(require("dotenv").load()が不要)
  • SQLite3クライアント
  • 多くのNode.jsのネイティブモジュール(fs,path,processなど)

Speed

https://twitter.com/jarredsumner/status/1499225725492076544
Twitterや公式サイトにもこんだけ早い!と紹介がありますが、自分でもコードを書いて速さを比べてみました。
私の環境は、こちらです。

まずは、作者のツイートにもあったベンチマークを実践。
非常に単純なJavaScriptファイルです。

// hello.js
console.log("Hi!")

  • bunの方がnodeの4.00倍高速
  • bunの方がdenoの1.69倍高速

作者のツイートと似たような結果になりました!

エラトステネスの篩を使った素数判定もしてみました。
素数 6,700,417 が素数かどうか判定してもらいます。

ソースコード
const N = 6700417;    
let arr = Array(N);    
let prime_flags = Array(N+1).fill(true);    
prime_flags[0] = false;    
prime_flags[1] = false;    
    
for(let i = 0; i < N+1; i++){    
  if(!prime_flags[i])    
    continue;    
  for(let j = i*i; j < N+1; j+=i)    
    prime_flags[j] = false;    
}    
    
console.log(prime_flags[N]);    

  • denoの方がnodeの1.48倍高速
  • denoの方がbunの1.11倍高速

あれ、denoが最速(とはいえ、1.11倍)
どこが原因なのか軽く調べてみました。

const N = 6700417;
let arr = Array(N);
node deno bun
31.3ms 14.0ms 11.6ms
  • bunの方がnodeの2.70倍高速
  • bunの方がdenoの1.21倍高速
const N = 6700417;
let arr = Array(N);
arr.fill(true);
node deno bun
37.6ms 20.4ms 21.2ms
  • denoの方がnodeの1.85倍高速
  • denoの方がbunの1.04倍高速

arr.fill(true)を加えたら最速がdenoになりました。
単純に引き算をしてfillメソッドにかかった時間を調べてみると。

node deno bun
6.3ms 6.4ms 9.6ms
  • nodeの方がdenoの1.02倍高速
  • denoの方がbunの1.52倍高速

nodeが最速!?
色々と検証すると面白そうですが、沼りそうなので手を引きます。
nodeが一番早い理由が分かる人はコメントいただけると嬉しいです。(ベンチマーク方法がおかしい?)

私の検証では、他のランタイムの方が早いという驚きの結果が出てしまいましたが、基本的にはbunの方が速そうです。それにbunはまだバージョン0.1.2、これからまた変わっていくかもしれません。

JavaScriptCore

Bun.jsはJavaScriptCoreと呼ばれるJavaScriptエンジンを使っています。
一般的に有名なJavaScriptエンジンはChromeやNode.js,Denoなどで使われているV8だと思いますが、JavaScriptCoreはV8より早い傾向があるようです。
ちなみに、JavaScriptCoreはiOSやmacOSアプリのSDKに標準装載されています。
https://developer.apple.com/documentation/javascriptcore

Zig

BunはZigと呼ばれるプログラミング言語で書かれています。
Zigは低レイヤーが得意なプログラミング言語で競合する言語は、C/C++やRustなどです。
RustとZigのどっちがいいかとかはググるとたくさん出てきました。
公式からの回答もあります。
https://ziglang.org/learn/why_zig_rust_d_cpp/

使ってみる

インストール

curl https://bun.sh/install | bash

プロジェクトの作成

Reactプロジェクトを作ります。

bun create react my-app

npx create-react-app my-appだと10秒以上かかるのに、1秒もかからない。早い。

実行

cd my-app
bun dev

感想

Web界隈はどんどん新しいモノが出てきますね...
denoもbunのどちらもnodeの代替となりそうですが毛色がだいぶ違います。
それぞれ住み分けすることになるのか、どちらか1強となるのか、はたまたnodeがこのままシェアを維持するのか気になるところです。
Bunはnpmクライアントをbuilt-inしているので、DenoよりはNodeからの移行はしやすそうです。(まだbetaなので使いにくいですが...)
とにかくbun installはめちゃくちゃ早いので是非試してみてください!

正式リリースされる頃にはもっと使いやすくなっていそうで楽しみです。
また、私のような素人ではなくWebエンジニアさんの知見からbunやdenoを比較した記事も読んでみたいなと思いました。できれば日本語で。

Bunの記事を書いといてなんですが、個人的にはBunよりZig言語の方が気になったのでこちらも少し勉強してみようと思います。
ここまで読んでいただきありがとうございました。

Discussion