1 ポイント 投稿者 GN⁺ 2025-01-25 | 1件のコメント | WhatsAppで共有
  • Bun 1.2は、フルスタックJavaScript/TypeScript開発ツールを目指し、Node.js互換性とランタイム・バンドラ・テスト・パッケージマネージャをあわせて拡張した大規模リリース
  • 変更のたびにNode.jsテストスイートを実行する方式で互換性検証を強化し、node:http2node:dgramnode:clusternode:zlibnode:v8のサポートを追加
  • 新しい組み込みAPI Bun.s3Bun.sql は、S3互換オブジェクトストレージとPostgresアクセスをランタイム内に取り込み、外部クライアントへの依存を減らす
  • パッケージマネージャは、デフォルトのlockfileをバイナリのbun.lockbからJSONCベースの**bun.lock**へ変更し、.npmrcbun publishbun patchbun outdatedbun run --filterを追加
  • bun runの作業ディレクトリ、Bun.build()の失敗処理、server.stop()の戻り値、bun -p、sourcemapのデフォルト値が変更されており、既存プロジェクトでは移行への影響を確認する必要がある

Node.js互換性の強化

  • Bun 1.2は、Bunの変更ごとにNode.jsテストスイートを実行する方式へと互換性改善の手順を変更
    • 従来はGitHub issueやnpmパッケージの実行失敗報告を中心にバグを修正していたが、この方法は大規模なリファクタリングを難しくする「モグラ叩き」に近かった
    • Node.jsリポジトリ内の数千のテストファイルをBun向けに移植し、各コミットごとにこれらのテストを実行して互換性を確認している
  • Node.jsのテストには、内部実装の詳細や正確なエラーメッセージを検証するものもあるため、Bunでは一部テストで内部バインディングを独自スタブに置き換えたり、namecodeを中心とした検証へ調整している
    • Bunは可能な限りNode.jsのエラーメッセージに合わせているが、namecodeが同じであれば、より役立つメッセージを提供する場合もある
  • 新たにサポートされるNode.jsモジュールと機能
    • node:http2: HTTP/2サーバーの作成をサポート。gRPCサーバーにも必要
    • node:dgram: UDPソケットのbind/connectをサポート
    • node:cluster: 複数のBunインスタンスを実行して複数CPUコアへ処理を分散可能
    • node:zlib: JavaScript実装をネイティブコードで書き直し、Bun 1.1より2倍高速化
    • node:v8: getHeapSnapshotwriteHeapSnapshotにより、BunヒープをChrome DevToolsで調査可能
  • node:http2サーバーは、Bun 1.2でNode.jsより2倍高速
  • expressは、node:http互換性の改善とBun HTTPサーバーの最適化により、Node.jsよりHTTPリクエストを最大3倍高速に処理
  • V8 C++ APIを使うC++アドオンのサポートも追加
    • Node.jsはV8、BunはJavaScriptCoreを使うため、実装難度が高い
    • BunはJavaScriptCore上にV8の公開C++ APIを実装し、cpu-featuresのようなパッケージが動作するようにしている
    • V8 C++ APIサポートは複雑なため、多くのパッケージではまだ未実装の機能がある可能性があり、node-canvas@v2node-sqlite3のようなパッケージのサポートを継続的に改善中

組み込みS3 API Bun.s3

  • Bun 1.2は、S3互換オブジェクトストレージを扱う組み込みAPI Bun.s3を追加
    • Amazon S3、Google Cloud Storage、Cloudflare R2など、S3 APIを実装したサービスとともに利用できる
    • ファイルの読み取り、書き込み、削除を、Web標準のBlobと互換性のあるAPIで処理する
  • s3.file()はS3ファイルへの遅延参照を返し、text()json()arrayBuffer()stream()などBunのFile APIと同じ方法で使える
  • BunのS3クライアントは、JavaScriptではなくネイティブコードで書かれている
    • Node.jsで@aws-sdk/client-s3を使う方法と比べ、S3バケットのファイルダウンロードが5倍高速
  • 書き込み機能としてwrite()writer()を提供
    • write()では文字列、Uint8ArrayBlobResponseなどをアップロードできる
    • writer()は大きなファイルに対してマルチパートアップロードを実行する
  • presign()は、特定ファイルのアップロードを許可するpresigned URLを生成
    • ユーザーに認証情報を公開したり、バケットへ不要なアクセス権を与えたりせずに、直接S3へアップロードさせられる
  • Bun.serve()と併用する場合、new Response(s3.file(...))は、サーバーがS3ファイルをダウンロードして再送する代わりに、presigned URLへリダイレクトする
    • メモリ、時間、サーバーがファイルをダウンロードする帯域コストを削減する
  • s3:// URLはBun.file()fetch()でも利用できる
    • fetch("s3://...")でアップロード、ダウンロード、削除が可能
    • デフォルトのS3Clientは、AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYのような環境変数で設定される

組み込みPostgresクライアント Bun.sql

  • Bun 1.2は、Postgresをサポートする組み込みSQLクライアント Bun.sqlを追加
    • Bunは従来から組み込みSQLiteクライアントを提供しており、今回のリリースでSQLデータベース対応の範囲を広げた
    • MySQLサポートを追加するpull requestもある
  • Bun.sqltagged-template literalでSQLを実行する
    • JavaScriptの値をSQLパラメータとして渡せる
    • 文字列エスケープとprepared statementを自動で利用し、SQL injectionを防ぐ
  • 結果は、カラム名をキーとするオブジェクト配列で返される
  • ネイティブコード実装と複数の最適化を採用
    • 自動prepared statement
    • クエリパイプライニング
    • バイナリwire protocol
    • コネクションプーリング
    • 構造キャッシュ
  • Node.jsで人気のPostgresクライアントを使う方法より、行の読み取りが最大50%高速
  • APIはpostgres.jsに着想を得ており、既存コードからBun組み込みSQLクライアントへ移行しやすいよう設計されている

パッケージマネージャーの変更

  • Bun 1.2 は、デフォルトの lockfile をバイナリの bun.lockb からテキストベースの bun.lock に変更
    • bun.lockbbun installnpm よりほぼ 30 倍高速にするのに役立っていたが、GitHub 上で内容を確認しづらく、pull request のレビューや merge conflict の解消が難しかった
    • Dependabot のようなツールでも lockfile の読み取りが難しかった
  • bun.lockJSONC ファイル
    • コメントと trailing comma をサポート
    • pull request の diff を確認しやすくなり、trailing comma によって merge conflict の可能性も減る
  • 新しいプロジェクトでは bun.lock を生成
    • 既存の bun.lockb プロジェクトは、自動マイグレーションなしで引き続きバイナリ lockfile をサポート
    • bun.lockb は長期的にサポートされ、bun addbun update でも引き続き更新される
    • bun install --save-text-lockfile で新しいテキスト lockfile へ移行可能
  • bun install は、テキスト lockfile への移行後も Bun 1.1 より 30% 高速化
  • package.json でコメントと trailing comma を使用可能
    • require()import() もこのような package.json を読み取れる
    • JavaScript エコシステム全体で広くサポートされている機能ではないため、「at your own risk」で使うよう案内している
  • .npmrc サポートを追加
    • プロジェクトルートとホームディレクトリの .npmrc を読み取る
    • registry、scoped package、private registry の認証設定に利用できる
  • 新しいパッケージマネージャーのコマンドとオプション
    • bun run --filter: 複数の workspace で同じスクリプトを同時実行
    • bun outdated: 古い依存関係を確認
    • bun publish: npm publish の代替で、.npmrc 認証・tarball packing・OTP・package.json の edge case 処理をサポート
    • bun patch: 依存関係の修正内容を patches/ 内の .patch ファイルとして保存し、bun install 時に自動適用
    • --omit=dev|optional|peer: インストール時に dev、optional、peer 依存関係を除外
    • CA 証明書は bunfig.toml、CLI フラグ、.npmrc で設定可能
    • bundleDependencies と、bun add における package.json のインデント保持もサポート

テストランナーの改善

  • bun test は JUnit XML レポーターをサポート
    • bun test --reporter=junit --reporter-outfile=junit.xml により、Jenkins、CircleCI、GitLab CI のような CI/CD ツールへテスト結果を渡せる
    • bunfig.toml でも JUnit レポートを設定可能
  • コードカバレッジには LCOV レポーターを追加
    • bun test --coverage --coverage-reporter=lcovcoverage/lcov.info を生成
    • --coverage-dir で出力ディレクトリを変更可能
  • expect().toMatchInlineSnapshot() で inline snapshot をサポート
    • bun test -u または --update-snapshots でテストファイル内の snapshot を更新
    • toThrowErrorMatchingSnapshot()toThrowErrorMatchingInlineSnapshot() も使用可能
  • test.only() は、もはや --only フラグなしでも動作
  • expect() API には Jest、Vitest、jest-extended のような matcher を追加
    • toContainValue()toContainKey()toHaveReturned() 系列
    • 2 番目の引数としてカスタムエラーメッセージを渡せる
  • jest.setTimeout()setDefaultTimeout() により、現在の scope または module のデフォルトのテスト timeout を変更できる

バンドラーとビルド機能

  • Bun 1.2 は HTML import をサポート
    • HTML ファイルを Bun.servestatic オプションに渡すと、HTML 内の <script><link> を自動でバンドルし、静的ルートとして公開する
  • bun build --compile はクロスコンパイルをサポート
    • Linux で Windows または macOS 向けバイナリを作成でき、その逆方向も可能
    • Windows ビルドではアイコン設定とコンソールウィンドウ非表示オプションを利用できる
  • bun build --bytecode は bytecode cache を生成
    • eslint のようなアプリケーションの起動時間を 2 倍高速にできる
    • .jsc ファイルは対応する .js ファイルの bytecode cache を保持し、実行には両方のファイルが必要
    • bytecode cache はソースコードより 8 倍大きくなる可能性があり、起動時間改善の代わりにより多くのディスク容量を使う
  • bun build --format=cjs で CommonJS の出力形式を指定可能
    • 以前は ESM のみをサポートしていた
    • 古い Node.js バージョンを対象としたライブラリやアプリケーションを作りやすくなる
  • CommonJS 検出を改善
    • ファイルが曖昧な場合、先頭の "use strict" ディレクティブを CommonJS 判定の最後のヒューリスティックとして使用
    • require.main === moduleimport.meta.main に書き換えられ、import 文と一緒に使える
  • プラグイン API には onBeforeParse() フックを追加
    • JavaScript ではなく N-API addon として実装する必要がある
    • Rust、C/C++、Zig のようなコンパイル言語で、パース直前のソースコードをほぼオーバーヘッドなしで扱える
    • プラグイン・フレームワーク作者向けの高度な API
  • ビルドオプションも拡張
    • --env="PUBLIC_*" で環境変数をバンドルに注入
    • --drop=console のような形で関数呼び出しを削除
    • banner/footer の追加
    • Bun.embeddedFiles() で standalone executable に含まれるファイル一覧を確認
    • --ignore-dce-annotations で誤った dead-code elimination annotation を無視
    • --packages=external でパッケージ依存関係をバンドルに含めないよう設定

CSS バンドリング

  • Bun 1.2 は新しい CSS parser と bundler を実装
    • LightningCSS の作業から派生し、Rust から Zig に書き直されて、Bun の JavaScript/TypeScript parser、bundler、runtime と統合された
  • bun build ./index.css で、複数の CSS ファイルと @importurl@font-face の参照を 1 つの CSS ファイルに結合できる
  • JavaScript および TypeScript のコードから .css ファイルを import できる
    • JavaScript module graph で import された CSS と @import ルールを、entrypoint ごとに 1 つの CSS ファイルへフラット化する
  • Bun.build() API でも、同じ API で CSS と JavaScript をバンドルできる

Bun ランタイムAPIの追加

  • Bun.serve()static プロパティで静的ルートをサポート
    • パスをキー、Response オブジェクトを値として渡す
    • 静的ルートは fetch() ハンドラーで直接処理するより最大40%高速
    • response body、header、status code がメモリにキャッシュされるため、JavaScript allocation と garbage collection が発生しない
    • server.reload() で静的ルートを再読み込みできる
  • Bun.udpSocket() は Bun API スタイルの UDP ソケットを提供
    • node:dgram もサポートするが、Bun.udpSocket() は既存の Bun.listen() に近いモダンな API
    • 単一の syscall で複数の UDP datagram を送信でき、OS の backpressure に対応
  • Bun.file()delete(), unlink(), stat() をサポート
    • stat() は Node.js fs.stat()Stats オブジェクトと同じ形式のメタデータを返す
    • S3 ファイルにも同じ API を使える
  • Bun.color() は色の解析、正規化、変換を提供
    • CSS、ANSI color code、RGB、HSL などをサポート
  • dns.prefetch() は DNS レコードを事前取得し、起動時に DNS cache をウォームアップできる
  • その他のユーティリティ
    • Bun.inspect.table(): console.table のような表形式の文字列を返す
    • Bun.randomUUIDv7(): ソートやデータベースに適した monotonic UUID v7 を生成

SQLite クライアントの改善

  • Bun 内蔵 SQLite クライアントは query.as(Class) でクエリ結果をクラスインスタンスにマッピングできる
    • getter、setter、method を付けられる
    • パフォーマンス上の理由から class constructor、default initializer、private field はサポートしない
    • リレーション管理や SQL 生成は行わないため ORM ではない
  • query.iterate() は行を一度にすべてメモリへ載せず、iterator として処理する
    • クエリオブジェクト自体も for ループで反復可能
  • strict オプションを有効にすると、クエリパラメータで $, @, : prefix を省略できる
    • パラメータが足りない場合はエラーを投げる
  • db.run() の結果で変更された行数と最後に挿入された row ID を確認できる
    • changes
    • lastInsertRowid
  • safeIntegers オプションは 64 ビット整数を切り詰められた number ではなく BigInt として返す
    • データベース単位またはクエリ単位で設定可能
  • JavaScript の using 構文で statement と database をスコープ終了時に自動で close できる

JavaScript からの C コンパイル・実行

  • Bun 1.2 は JavaScript から C をコンパイルして実行する実験的サポートを追加
    • bun:fficc() API を使用
    • 別途 build step なしで JavaScript から C system library を使える仕組み
  • Bun には tinycc が内蔵されている
    • gccclang と異なり、単純な C コードをミリ秒単位でコンパイルできる
    • 必要なときに C コードをコンパイルして実行できる
  • N-API を使う C コードも提供される
    • node-gyp のビルド段階なしで Bun だけあれば動作する

musl と Alpine Linux のサポート

  • Bun 1.2 は glibc の代わりに musl libc を使う Linux ディストリビューション向けの Bun ビルドを追加
    • Alpine Linux のような環境で使える
    • Linux x64 と aarch64 をサポート
  • Docker では oven/bun:alpine イメージを使用できる
  • musl はより小さなコンテナイメージを可能にする一方、Bun の glibc 版よりやや遅い傾向がある
    • 特別な理由がなければ glibc の使用を推奨

JavaScript 言語機能

  • import attributes のサポートを追加
    • import json from "./package.json" with { type: "json" } のように JSON、text、TOML などを明示して import できる
    • 動的 import() でも使える
  • usingawait using をサポート
    • スコープを抜けると [Symbol.dispose] または [Symbol.asyncDispose] が呼ばれ、リソースを自動的に解放する
    • Bun.spawn(), Bun.serve(), Bun.connect(), Bun.listen(), bun:sqlite など複数の Bun API でサポート
  • Promise 関連の新 API
    • Promise.withResolvers(): promise, resolve, reject をまとめて生成
    • Promise.try(): 同期または非同期関数を promise で包む
  • エラーとバイト配列 API
    • Error.isError(): prototype chain の操作や node:vm の cross-realm 状況でも、より正確に Error かどうかを判定
    • Uint8Array.toBase64() / Uint8Array.fromBase64()
    • Uint8Array.toHex() / Uint8Array.fromHex()
  • iterator helper を追加
    • map, flatMap, filter, take, drop, reduce, toArray, forEach, find
  • Float16Array をサポート
    • 16 ビット浮動小数点配列は 32 ビットより精度は低いが、メモリ効率が高い

Web API の追加

  • TextDecoderStreamTextEncoderStream をサポート
    • TextDecoderTextEncoder のストリーミング版
    • Bun では TextEncoderStream は Node.js より最大30倍高速
  • TextDecoderstream オプションをサポート
    • chunk が完全な UTF-8 code point でなくても、より大きなストリームの一部として処理できる
  • bytes() メソッドを追加
    • ResponseBlobBun.file() などで stream データを Uint8Array として返す
    • 従来の arrayBuffer() のあとに Uint8Array を生成する手間を減らす
  • ストリーミング fetch() upload をサポート
    • 大きなファイルや content length を事前に把握できないデータストリームのアップロードに有用
  • console.group()console.groupEnd() を実装
  • URL.createObjectURL() をサポート
    • Blob から URL を作成し、fetch()Workerimport() に使える
    • Worker script も Bun transpiler を通るため TypeScript 構文を使える
  • AbortSignal.any() は複数の AbortSignal を結合し、1 つが abort されると親 signal も abort されるようにする

動作変更と移行時の注意点

  • bun run作業ディレクトリが変更
    • 以前は shell の現在の作業ディレクトリを使用
    • Bun 1.2 では package.json の親ディレクトリをスクリプトの作業ディレクトリとして使用
    • npmyarn の動作に合わせるための変更
  • bun test はテスト間の uncaught error または rejection を失敗として報告
    • 以前はこのようなエラーがテスト失敗として処理されないことがあった
  • server.stop() は теперь Promise<void> を返す
    • in-flight な HTTP connection が閉じるまで待機可能
  • Bun.build() は失敗時、resolve された結果の logs にエラーを入れる代わりに reject する
    • 従来の動作が必要なら throw: false を設定可能
  • bun -p は Node.js に合わせて bun --print の alias になる
    • 以前は bun --port の alias だった
  • bun build --sourcemap のデフォルト値が inline source map から linked source map に変更
    • 以前の動作が必要なら --sourcemap=inline を使用

パフォーマンス改善

  • Bun 1.2 には複数の実行経路でパフォーマンス改善が含まれる
    • node:http2: 2倍高速
    • node:http 経由の S3 アップロード: 5倍高速
    • path.resolve(): 30倍高速
    • fetch() DNS resolution: 2倍高速
    • bun --hot: メモリ使用量が2分の1
    • macOS fs.readdirSync(): 小さなディレクトリの読み取りが5%高速化
    • String.at(): 44%高速化
    • 大きな文字列入力の atob(): 最大8倍高速
    • fetch() gzip データの展開: 30%高速
    • 大きな入力の Buffer.from(string, "base64"): 6倍〜30倍高速
    • 大きな文字列入力の JSON.parse(): 2倍〜4倍高速、object 入力は 6%高速
    • 一部の Bun.serve() アプリケーションのスループット: 最大2倍向上
    • Error.captureStackTrace(): 9倍高速
    • 小さなファイルの fs.readFile(): 最大10%高速
    • 文字列引数の console.log(): 50%高速
  • Windows では JavaScriptCore の JIT が有効化
    • 以前は JIT は macOS と Linux でのみ利用可能だった
    • Windows で JavaScript が全体的により高速に実行される
    • 例として Object.entries() は20%、Array.map() は50%高速化

インストールとアップグレード

  • 新規インストールコマンド
    • curl -fsSL https://bun.sh/install | bash
    • powershell -c "irm bun.sh/install.ps1 | iex"
    • npm install -g bun
    • brew tap oven-sh/bun の後に brew install bun
    • docker pull oven/bun
  • すでにインストール済みの Bun は bun upgrade でアップグレード

1件のコメント

 
GN⁺ 2025-01-25
Hacker News の意見
  • なぜサードパーティのデータベース外部 S3 ライブラリをコア/標準ライブラリに入れるのか分からない
    こういうものは任意のライブラリのほうがよいのではないかと思うし、この種のランタイムは標準ライブラリに入れる項目を非常に慎重に選ぶべき
    早くもキッチンシンクのように何でも詰め込むプロジェクトという印象がある

    • こういう姿勢自体が Bun が注目された理由の一つだと思う
      バッテリー同梱方式は多くの場面で人気があり、選ばれている道でもある
      TypeScript の設定も難しいし、Webpack、S3、Postgres、Jest なども同様なので、単純化されたファイル/ストリームアクセスもかなり興味深い
      分散デプロイ提供者がどう出てくるか見守ればよさそう
    • Bun は VC から投資を受けていると理解しているので、いつかは収益を上げなければならず、だから推測するに、オールインワン実行環境にして何らかの形でベンダーロックインを作ろうとしているのかもしれない
      もちろん間違っているかもしれないが、こうした依存関係をコア/標準ライブラリに入れるのは実際あまり筋が通らない
    • 多くの人が Bun の作者である Jared に同じことを言ってきたが、Jared の考えは Bun が基本プロジェクトに必要なものをすべて備えるべきだという方向
      コアに入れればサードパーティライブラリよりさらに最適化できると見ているようだ
      個人的には誤ったアプローチで、Jared は野心が大きくなりすぎた感じがするが、結局は彼の情熱プロジェクトではある
    • 任意のライブラリのほうがよいという点には完全に同意する
      Bun 側の表現では「Bun はクラウドファーストの JavaScript ランタイムを目指している。つまり、クラウドでプロダクションアプリケーションを実行するために必要なすべてのツールとサービスをサポートする」ということだが、この言葉はあまり信頼感を与えない
      この特定の設計選択はNode よりさらに悪く見える
    • これは Bun のマネージド提供サービスのためのもの
      VC 支援ソフトウェアの問題は、こうした統合機能が常に独自の何かを提供しようとし、言い換えればロックインを作ろうとするところにあった
  • これまでの Bun の使用体験は非常によかった
    新しいプロジェクトで TypeScript/Jest/React/Webpack を設定するとき、あちこちの破壊的変更のせいでいつも気が進まなかったが、Bun では自前で解決されていて、苦痛なく自分の用途ではそのまま動く
    S3 や SQL のようなサードパーティライブラリ統合については何とも言いにくいが、少なくとも最も一般的に使われ、要望の多いものに集中しているように見える
    Node.js ツールエコシステムに必要だった健全さをもたらしてくれてよい

    • 上で挙げられているフロントエンド技術スタックで、Bun がどんな違いを生むのか気になる
    • React/TypeScript プロジェクトは Vite や Next.js でもうまく設定できてきた
      他のツールもこの間かなり進歩した点を過小評価しているように思う
    • Bun は素晴らしい
      自分にとっては生産性のチートコードのような存在
      ChatGPT が Bun をよく知らないので生産性の損失が少しあるが、それでも Bun が好き
  • よい内容は多いが、デフォルト動作の一部があまりにも魔法のように隠れた動作に向かっているのではないかと心配
    new Response(s3.file(...)) を使うと、S3 ファイルをサーバーにダウンロードしてユーザーに送る代わりに、Bun がユーザーを S3 ファイルの事前署名付き URL にリダイレクトする
    デフォルトとしてはかなり驚く選択で、S3 バケットを直接露出したくない場合にこれをどう無効化するのかもまったく明確ではない

    • Bun が切り開こうとしている領域は尊重するが、作者を Twitter でフォローしていると、意思決定が短期的な成果と利便性にかなり偏っており、その魔法的動作の深い影響は軽く扱う傾向がある
      当初はこのプロジェクトに期待していたが、ソーシャル上で公開される散発的で、個人的にはしばしば好ましくない設計判断を見ると、長期的な方向性を信頼できない
      v0.x のままならよかったかもしれないが、1.0 を出したなら API 表面を増やす基準はずっと高くあるべきだった
    • レスポンスにストリームを渡せばよい
      Response(file.stream())
    • なぜそうしたのかは分かるが、この設計は好きではない
      個人的には副作用の強い動作のように感じるし、読む限りでは URL ではなくファイル内容を返すように見える
      それでもバケットの露出の何が気に障るのかも気になる
      事前署名付き URL なので、広範なアクセス権を与えるわけでもない
      むしろ Response((file(...).getPresignedURL())) のような明示的 API のほうがよく、あるいは環境変数や Bun の設定でこの動作を有効化できる選択肢のほうがよかったと思う
  • バッテリー込みは大きな違いを生む
    Fetch API、Service Workers、Web Components、ES6+、WebRTC のような Web API が、いまでは V8 と WebKit ランタイムの両方でネイティブになっている点を好ましく思う理由もそこにある
    ただし限度はあるべき
    S3 は行き過ぎかもしれないが、SQL ドライバーは理にかなっている
    とはいえ、どこまで入れるかが問題
    データベースは非常に多く、そのうち半分のドライバーを入れるべきなのか?
    そのレベルだけでも追加コードが多くなり、実行ファイルが遅くなる可能性がある
    また、このようなセンシティブな API を Bun に入れると、セキュリティも見落としかねない
    何らかのスクリプトやパスの問題で eval が実行され、Bun がソースファイル全体を個人の S3 にアップロードするところを想像してみると、その瞬間に終わり

    • 「追加コードが多くなると実行ファイルが遅くなる」というのが本当にそうなのか気になる
      コードがランタイムにロードされる方式によっては、ほとんど無視できるレベルかもしれないと思った
      import 文が見えたときだけコードのロードがトリガーされるなら、実質的に速度オーバーヘッドはないのでは?
      静的リンクされていたとしても、コードが存在するという理由だけで、考慮に値するほど実行ファイルが遅くなる理由はよく分からない
      メモリにロードする実行ファイルが文字どおり大きくなる程度はあるだろうが、体感できる遅さではなさそう
    • 以前 HN で、ブラウザーが SQLite をファーストクラスでサポートしない理由についての議論があったが、その論点は Bun にも当てはまり得る
      核心は、ライブラリの保守責任が誰にあり、SQLite が変わったときにそのライブラリをどう変えるかということ
      SQLite にバグがあったら、Bun ではどう直すのか?
      どのバージョンに修正を入れるべきなのか?
      ランタイムのパッチがその上で動くコードの挙動を変え得るが、ユーザーが既存の挙動に合わせて回避策を入れていた場合はどう扱うのか?
      ある程度は解決可能な問題だが、デメリットも伴う
      ある時点から、ランタイムではなく プラットフォーム になり、それに伴う別の責任と問題が付いてくる
    • S3 を入れようという側の根拠は、S3 互換 API を実装したオブジェクトストレージサービスが多い点にあると思う
      本物の Web 標準ではないが、多くの人が事実上の標準のように合わせて使っている対象でもある
    • 「追加コードが多くなると実行ファイルが遅くなる」とはいうが、記事には文字どおりベンチマークがあり、Bun は最速の Node.js ソリューションより 2倍速い と出ている
  • 最近、顧客企業が本番環境で Bun を使っている
    速度とシンプルさのおかげで、Bun の開発体験はとんでもなく良いと聞いた
    開発者体験 は長期的に大きな役割を果たす
    コードベースやプロセスがめちゃくちゃだと、FAANG 級の報酬を出さない限り、優秀な人材を失うことになる

  • まだ Bun は使っていないが、機能一覧が長すぎて、すべてが堅牢でバグがないのかは懐疑的
    自分が間違っていてほしいし、今後のプロジェクトで一度動かしてみるつもり
    プロジェクト管理の観点では、まだ Node.js 100% 互換 でもないのに、なぜ S3 サポートに時間を使うのか少し混乱する
    Next.js は非常に大きなエコシステムなので、Next.js の顧客を取り込めるなら、S3 サポートよりはるかに大きく成長できる

    • 100% 互換はマーケティング上は良い勝利だが、ロングテールの互換性が平均的なユーザーにとって大きな違いを生むとは限らない
      日常的に Node.js API サーフェス 全体のうち、実際にどれだけ使っているのか?
      その中の奇妙なエッジケースに、実際どれだけ依存しているのか?
    • 「プロジェクト管理の観点」という言い方は、そのプロジェクトが何なのか分かっていると仮定している
      作業している人たちもロボットではない
      ある作業は把握するのに時間がかかり、その間に別の作業をすることもできる
      1人がすべてをやっているわけでもない
      「Next.js の顧客を取り込めばもっと成長する」というが、何に向けた成長なのか?
      それはお金にならない
      これは VC 支援のプロジェクトであり、目標は Bun を無料で提供して世界中のユーザーを全員獲得することではない
    • 長い機能一覧がすべて堅牢でバグがないのか疑わしいが、特に Zig で書かれている という点が引っかかる
      Zig はメモリ安全性が非常に低い
      もう生存していない変数を参照すると、セグメンテーションフォルトではなく、任意の無関係なメモリにアクセスする
      デバッグモードやセーフモードでもそうだという[0]
      変数名を死んだ状態としてマークし、死んでいればアクセスを防ぐメモリ生存性システムを上に載せるのは、そんなに難しいのか?
      結局「未定義動作を使うな」[1] になる
      だから、インターネットに公開される Web サーバーのようなところには、Zig 製のものは何も置きたくない
      [0] : https://news.ycombinator.com/item?id=41720995
      [1] : https://github.com/ziglang/zig/issues/16467#issuecomment-164...
    • それほど堅牢でも、バグがないわけでもない
      去年使ってみたが、ずっとクラッシュしていた
    • bun addpackage.json の空白とインデントを保持しないバグを修正し、今ではどれほど変なインデントでも保持するという項目がかなり笑える
      誰がこんなものを求めたのか、そしてなぜここにコードを書く価値があると考えたのか分からない
  • HTML のインポート がすごくて格好いい
    Bun 1.2 で HTML のインポートをサポートし、フロントエンドのツールチェーン全体を単一の import 文で置き換えられるという
    Bun.servestatic オプションに HTML インポートを渡せば始められる

    import homepage from "./index.html";
    
    Bun.serve({  
      static: {  
        "/": homepage,  
      },
    
      async fetch(req) {  
        // ... api requests  
      },  
    });  
    
    • これが例えば Vite をどう置き換えられるようにしてくれるのか気になる
      ホットモジュール置換、CSS プリプロセス、Vue SFC コンパイラのようなフレームワーク別プラグインのロードは可能なのか?
      静的ファイル配信は特に新しいものではないので、自分が何か見落としている気がする
  • Node.js の競合代替ほど失敗が約束されたプロジェクトもないと思っていたが、一度使ってみてよかった
    テキストファイルと SQLite DB の更新を処理するスタンドアロンの実行スクリプトをたくさん作る必要があり、TypeScript、bun:sqlite [1]、bun $ Shell [2] を設定ファイルやローカルの npm 依存関係管理なしでそのまま使えた
    その後、新しい JS/TypeScript プロジェクトでも使ってみたところ、内蔵バンドラー [3] やテストサポート [4] も活用でき、依存関係のインストールも一瞬で終わった
    すべてが高速にすぐ動くのは実際に生活の質を上げてくれるもので、いまや Bun は新しい JS プロジェクトの第一候補になっている
    [1] https://bun.sh/docs/runtime/shell
    [2] https://bun.sh/docs/api/sqlite
    [3] https://bun.sh/docs/bundler
    [4] https://bun.sh/docs/cli/test

    • 私も同じ
      「こういうものは来年には npm にも全部入るだろうし、何の意味があるのか」という側だった
      結局 Bun を使ってみて、本当に驚いた
      開発者体験の小さな要素が積み重なると大きな差になる
      自分のプロジェクトでは、Bun は本当に次世代のもののように感じる
  • 少し前に初めて Bun を使ってみたが、体験は素晴らしかった
    自分のすべてのプロジェクトでは TypeScript を使うために Webpack や Vite を設定していて、一度設定すればほぼ完璧に動くが、設定そのものが面倒で、小さなスクリプトにはそこまでする価値がない
    一方で Bun はすぐに動いた
    CLI で TS を「直接」実行しようとして、node-ts か何かのツールを 10〜30 分いじりながら、「モジュールではない」「import/require が使えない」「ESM/CJS」といったひどいメッセージに対応し、よくある修正である package.json のモジュールタイプ変更、tsconfig の変更、import/require 方式の変更をすべて試した
    約 200 行のスクリプトを実行しようとして、最後の手段として Bun に切り替えたところ、見事に動いた

    • 最新の Node.js も、こういう場合には今では「そのまま TS を実行」することをサポートしている
      node --experimental-strip-types index.ts
      最新の Node でなければ、tsx パッケージが自分にはうまく動いた
      ts-node よりよかった
      ただし、どちらの選択肢も型情報を単に捨てるだけで、Bun も同じ
  • 方向性が気に入っている
    特に S3 と Postgres のネイティブサポートを含めたのは、「自分でフレームワークを組み立てる」現状の代替として存在する価値があり、とても妥当だ
    Rails や Laravel のようなあらゆる Web フレームワークではこれが標準であり、JS エコシステムもここから大きな恩恵を受けられる
    次のステップは、マイグレーションとスキーマ管理、そしてファクトリー設定をうまく扱える、より優れた標準のテスト体験だと思う