速くてAll in OneなJavaScriptランタイム 「Bun」

2022.07.19

Introduction

JavaScriptランタイムといえば一般的にはNodeかDenoが思い浮かびます。
Bunはこれらに並ぶ選択肢に
なりえるかもしれないJavaScriptランタイムです。

Bunは、下記ポイントに焦点を当てて開発されているとのこと。(公式より)

  • Start fast(エッジを考慮して設計)
  • 新しいレベルのパフォーマンス(JavaScriptCoreエンジンを拡張)
  • All in One(bundler, transpiler, package managerが統合)

Bunは、ローカルマシン、サーバサイド、Edge環境で現在のJavaScriptや
TypeScriptのアプリやスクリプトを
リプレイスするものとして開発されています。
(WASMとかぶる?)
現状、Node API関数の90%以上をネイティブで実装しているそうです。

簡単にいうと、Bunは「速くてAll in OneなJavascriptランタイム」です。

About Bun

Zig言語JavaScriptCoreで実装されているBunについて、
特徴を簡単に紹介します。

アイコンのこいつ

まず気になったのがこれ。

肉まんとかまんじゅうとか赤ちゃんとか言われてますが、
こいつは何者なのか気になります。
bunでしらべるとパンの画像や団子(Google翻訳)とでてくるので、
おそらく食べ物だと思いますが、具体的に何かは不明。
日本だと肉まんと呼ばれてるのを何度か見かけました。

各種ツールが統合

Nodeの場合、パッケージマネージャはnpmやyarnを使い、
バンドラーはwebpackを使用、TypeScriptのトランスパイルは
typescriptパッケージを使います。

Bunの場合、自身がパッケージマネージャ(npm互換)やバンドラーの機能をもっています。
さらに(Denoのように)TypeScriptのトランスパイルもデフォルトで可能です。
(JSXのトランスパイルも可能)

タスクランナーとして動かすことも可能なので、ここにあるように、
npm runするみたいにタスクランナーの使い方もできます。

例えば下記のようなcleanタスクは

{
  "name": "myapp",
  "scripts": {
    "clean": "rm -rf dist out node_modules"
  }
}

bun run <コマンド> (またはbun <コマンド>)
で実行できます。

% bun run clean
 or 
% bun clean

速い

動作の速さをとにかくアピールしてます。
パッケージインストールを例にとると、 bun install(bunのnpm installみたいなやつ)は
Linux環境だとnpm installの20倍〜100倍速いそうです。
(macの場合だと4倍〜80倍くらい速いとのこと)

ここでいっているように
↓のスクリプトで、260,000 req/s(M1 Max)のパフォーマンスをだせるそうな。

// http.ts
export default {
  port: 3000,
  fetch(request: Request) {
    return new Response("Hello World");
  },
};

さらにここではHTTPサーバーの処理比較で、
BunがNode.jsより約2.5倍のリクエストを処理しています。

Requests per second Runtime
~64,000 Node 16
~160,000 Bun

ただ、この記事で比較しているように、
ケースによってはNodeが速かったりDenoが速かったりするので、
常にBunが最速というわけではないようです。

その他機能

上記以外の機能もいろいろ。  

普通にトップレベルawaitが使えます。

//foo.js
const blob = Bun.file("input.txt");
await Bun.write("output.txt", blob);

あとは.envから自動で環境変数をロードしてくれたり、
SQLite3クライアントがデフォルトで組み込まれていたります。

なお、紹介した以外の機能や各種詳細についてはGithubのREADMEで確認してください。
現状のドキュメントはこれだけです。
ここみれば、CLIの使い方からnodeとの比較まで全部のってる感じです。

Setup

ではBunをインストールしてみます。
公式にあるようにcurlでインストールスクリプトを実行すればOKです。

% curl https://bun.sh/install | bash
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  5046    0  5046    0     0  30957      0 --:--:-- --:--:-- --:--:-- 30768
######################################################################## 100.0%
bun was installed successfully to /User/hoge/.bun/bin/bun

% bun --version
0.1.4

HTTPサーバのサンプルを記述。

// http.js
export default {
  port: 3000,
  fetch(request) {
    return new Response("Welcome to Bun!");
  },
};

bunコマンドでHTTPサーバが起動します。

% bun run http.js
or 
% bun http.js #これだと補完がきかなかったが

% curl http://localhost:3000
Welcome to Bun!%

Bun CLI

基本的なCLIのコマンドについて紹介します。
Bun CLI参照

bun run

さきほども使用したスクリプト実行コマンドです。
js/tsファイルを実行します。
また、package.jsonに記述したスクリプトを実行するこも可能。

bun install (bun i)

package.jsonに記述された依存ライブラリをインストールします。
このコマンドではパッケージを指定してインストールすることはできません。
その場合は後述するaddを使いましょう。

bun add (bun a)

パッケージを指定してインストールします。
npm install --saveみたいな感じ。

% bun add mocha
bun add v0.1.4

 installed mocha@10.0.0 with binaries:
  - mocha
  - _mocha

bun remove (bun rm)

インストールしたパッケージを削除します。

% bun rm mocha
bun remove v0.1.4
[26.00ms] done
No packages! Deleted empty lockfile

bun upgrade

Bunを最新に更新。

% bun upgrade
Congrats! You're already on the latest version of bun (which is v0.1.4)

bun create (bun c)

テンプレートを指定して、新規プロジェクトを作成します。
テンプレートなし(blank)もできますし、 Githubのリポジトリを指定することもできます。

% bun create
Welcome to bun! Create a new project by pasting any of the following:

  bun create blank ./blank-app

  bun create bun-bakery ./bun-bakery-app

  bun create discord-interactions ./discord-interactions-app

  bun create hono ./hono-app

  bun create next ./next-app

  bun create react ./react-app

# You can also paste a GitHub repository:

  bun create ahfarmer/calculator calc

試しにhonoで作成。

% bun create hono

$ bun install
bun install v0.1.4
  🔍 Resolving [1/2]
[95.00ms] git
 + bun-types@0.1.4
 + hono@2.0.2

 2 packages installed [1.78s]

[1.78s] bun install


[3.10s] bun create hono

Come hang out in bun's Discord: https://bun.sh/discord

-----

A local git repository was created for you and dependencies were installed automatically.

Created hono project successfully

そのままstartできます。

% cd hono
% bun run start

$ bun run src/index.ts
Running at http://localhost:3000

# curlで動作確認
% curl http://localhost:3000
{"message":"Hello World!"}%

Summary

今回はあたらしいJavaScriptランタイム、Bunを動かしてみました。
Bunは特別何かが革新的ということではなく、既存(主にNode)のプロダクトを
より速く、より便利につかえるようにした感じです。

ただ、ここでも言及しているように、
Bunが現状、ほとんど個人(Jarred Sumner氏)で開発しているプロダクトであることや、
Nodeとの互換性などの懸念点もあります。

とても魅力的なプロダクトですが、
まだベータ段階なので、しばらくは暖かく見守っていきましょう。

References