0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Bun でバンと始める爆速 JS/TS 開発 ── Node.js も npm も webpack も Jest もこれ一つ

0
Posted at

はじめに

この記事では、JavaScript と TypeScript のための高速なオールインワンツールキットである Bun の概要と実装方法を記載します。

Bun とは

Bun は、ランタイム、パッケージマネージャー、バンドラー、テストランナーを単一のバイナリに統合しています。

以下のような特徴があります。

  • Node.js より圧倒的に高速
    • 起動時間が最大4倍速く、HTTPリクエスト処理も約4倍のスループットを実現
  • TypeScript、JSX を追加設定なしで実行可能
    • トランスパイル設定が不要で、そのまま実行できる
  • Node.js との高い互換性
    • 既存の npm パッケージがそのまま使える
  • 統合されたツールチェーン
    • パッケージマネージャー、バンドラー、テストランナーが標準搭載
  • ネイティブ API の充実
    • SQLite、Web API、ファイル操作などを標準サポート
  • npm より高速なパッケージインストール
    • 依存関係の解決とインストールが大幅に高速化

従来の Node.js 開発では、用途ごとに個別のツールを組み合わせる必要がありました。Bun はこれらを単一のバイナリに統合しています。

役割 従来のツール Bun
ランタイム Node.js bun run
パッケージマネージャー npm / yarn / pnpm bun install
バンドラー webpack / Vite / esbuild bun build
テストランナー Jest / Vitest bun test
TypeScript 実行 ts-node / tsx 追加設定不要でそのまま実行
環境変数の読み込み dotenv .env を自動読み込み
開発サーバー Vite dev server / webpack-dev-server bun dev(HMR 標準搭載)

Bun という名前は英語で「丸パン・ロールパン」を意味し、ロゴもハンバーガーのバンズ(bun)をモチーフにしています。JavaScript 開発に必要なすべてを一つにまとめた、シンプルで高速なツールを目指して開発されています。

開発環境

開発環境は以下の通りです。

  • Windows 11
  • Bun 1.3.5
  • TypeScript 5.7.2

インストール

Windows

PowerShell を開いて、以下のコマンドを実行します。

powershell -c "irm bun.sh/install.ps1 | iex"

インストール後、新しい PowerShell ウィンドウを開いてバージョンを確認します。

bun --version

コマンドが認識されない場合

もし bun コマンドが認識されない場合は、まず以下でバイナリが存在するか確認します。

& "$env:USERPROFILE\.bun\bin\bun" --version

これが動作する場合、PATH に追加する必要があります。以下のコマンドを実行してください。

[System.Environment]::SetEnvironmentVariable(
  "Path",
  [System.Environment]::GetEnvironmentVariable("Path", "User") + ";$env:USERPROFILE\.bun\bin",
  [System.EnvironmentVariableTarget]::User
)

その後、PowerShell を再起動して、再度 bun --version を実行してください。

npm を使う場合

npm install -g bun

基本的な使い方

プロジェクトの初期化

新しいプロジェクトを作成します。

bun init

対話形式でプロジェクト名やエントリーポイントを設定します。
以下の例では、Reactのプロジェクトを作成しました。

✓ Select a project template: React
✓ Select a React template: Default (blank)

 + bunfig.toml
 + package.json
 + tsconfig.json
 + bun-env.d.ts
 + README.md
 + .gitignore
 + src/index.ts
 + src/App.tsx
 + src/index.html
 + src/index.css
 + src/APITester.tsx
 + src/react.svg
 + src/frontend.tsx
 + src/logo.svg


✨ New project configured!

Development - full-stack dev server with hot reload

    bun dev

Static Site - build optimized assets to disk (no backend)

    bun run build

Production - serve a full-stack production build

    bun start

Happy bunning! 🐇

上記の通り、テンプレートに応じたファイルが自動生成されます。主なファイルは以下の通りです。

  • package.json - プロジェクト設定
  • bunfig.toml - Bun の設定ファイル
  • tsconfig.json - TypeScript 設定
  • src/index.ts - サーバー側エントリーポイント
  • src/App.tsx - React コンポーネント
  • src/index.html - HTML テンプレート
  • README.md - ドキュメント

ローカルサーバーを起動します。Vite の vite dev に相当する機能が Bun に標準搭載されており、HMR(Hot Module Replacement)も追加設定なしで動作します。

bun dev

http://localhost:3000/ にアクセスすると以下の画面が表示されます。

image.png

TypeScript ファイルをそのまま実行

Node.js で TypeScript を実行するには、通常 ts-nodetsx などのツールを別途インストールし、トランスパイルの設定が必要です。Bun では TypeScript を追加設定なしでそのまま実行できます。

index.ts
const message: string = "Hello, Bun!";
console.log(message);

// Bun のネイティブ API
console.log(`Bun version: ${Bun.version}`);
console.log(`Platform: ${process.platform}`);

実行:

bun run index.ts

トランスパイルの待ち時間なしで、即座に実行されます。

Hello, Bun!
Bun version: 1.3.5
Platform: win32

Watch モード

ファイルの変更を監視して自動的に再実行します。

bun --watch index.ts

開発時の生産性が大幅に向上します。

Web サーバーの構築

Bun.serve による高速サーバー

Node.js で HTTP サーバーを構築する場合、標準の http モジュールは低レベルなため、多くのプロジェクトでは Express や Fastify といったフレームワークを別途インストールして使います。Bun は標準の Bun.serve だけで、ルーティング機能付きの高速な HTTP サーバーを構築できます。v1.2.3 以降では routes オプションが導入され、Express ライクなルーティングを外部ライブラリなしで定義できるようになりました。

server.ts
const server = Bun.serve({
  port: 3000,
  routes: {
    "/": () => new Response("Hello, Bun!", {
      headers: { "Content-Type": "text/plain" },
    }),

    "/api/users": () => Response.json([
      { id: 1, name: "Alice", email: "alice@example.com" },
      { id: 2, name: "Bob", email: "bob@example.com" },
    ]),
  },

  // routes にマッチしなかったリクエストのフォールバック
  fetch(req) {
    return new Response("Not Found", { status: 404 });
  },
});

console.log(`Server running at http://localhost:${server.port}`);

実行:

bun run server.ts

ブラウザで http://localhost:3000 にアクセスすると、レスポンスが表示されます。

image.png

routes オプションでは、HTTP メソッドごとのハンドラやダイナミックルーティングも定義できます。

const server = Bun.serve({
  port: 3000,
  routes: {
    // ダイナミックルーティング
    "/api/users/:id": (req) => {
      return Response.json({ id: req.params.id });
    },

    // HTTP メソッドごとのハンドラ
    "/api/posts": {
      GET: () => Response.json([{ id: 1, title: "Hello" }]),
      POST: async (req) => {
        const body = await req.json();
        return Response.json({ message: "Created", ...body }, { status: 201 });
      },
    },
  },
});

Express を使ったサーバー

既存の Node.js フレームワークもそのまま使えます。

bun add express
bun add -d @types/express
express-server.ts
import express from "express";

const app = express();
const port = 3000;

app.use(express.json());

app.get("/", (req, res) => {
  res.send("Hello from Express on Bun!");
});

app.get("/api/users", (req, res) => {
  res.json([
    { id: 1, name: "Alice" },
    { id: 2, name: "Bob" },
  ]);
});

app.post("/api/users", (req, res) => {
  const user = req.body;
  res.status(201).json({ message: "User created", user });
});

app.listen(port, () => {
  console.log(`Express server at http://localhost:${port}`);
});

実行:

bun run express-server.ts

image.png

image.png

image.png

パッケージ管理

パッケージのインストール

JavaScript のパッケージ管理には従来 npm、yarn、pnpm といったツールが使われてきました。Bun のパッケージマネージャーはこれらと互換性を保ちつつ、依存関係の解決とインストールを並列処理することで圧倒的に高速な動作を実現しています。コマンド体系も npm に近いため、移行のハードルは低いです。

操作 npm yarn Bun
パッケージ追加 npm install react yarn add react bun add react
開発依存追加 npm install -D yarn add -D bun add -d
一括インストール npm install yarn install bun install
パッケージ削除 npm uninstall yarn remove bun remove
スクリプト実行 npm run dev yarn dev bun run dev
# パッケージの追加
bun add react
bun add -d typescript

# 開発依存関係として追加
bun add --dev @types/node

# グローバルインストール
bun add -g typescript

package.json の依存関係を一括インストール:

bun install

パッケージの削除

bun remove react

npm プロジェクトからの移行

既存の npm プロジェクトで Bun を使う手順:

# 1. プロジェクトディレクトリに移動
cd your-project

# 2. Bun で依存関係をインストール
bun install

# 3. npm scripts を Bun で実行
bun run dev
bun run build
bun run test

テストランナー

Node.js のプロジェクトでテストを行う場合、Jest や Vitest といった外部ツールのインストールと設定が必要です。特に TypeScript プロジェクトでは、Jest に ts-jest@swc/jest などのトランスフォーマーを追加する手間もかかります。

Bun には Jest 互換のテストランナーが組み込まれており、describetestexpect といったおなじみの API をそのまま使えます。TypeScript のテストも追加設定なしで実行でき、Jest や Vitest と比べても高速に動作します。

テストの作成

math.ts
export function add(a: number, b: number): number {
  return a + b;
}

export function multiply(a: number, b: number): number {
  return a * b;
}

export function divide(a: number, b: number): number {
  if (b === 0) {
    throw new Error("Division by zero");
  }
  return a / b;
}
math.test.ts
import { expect, test, describe } from "bun:test";
import { add, multiply, divide } from "./math";

describe("Math functions", () => {
  test("add: 2 + 3 = 5", () => {
    expect(add(2, 3)).toBe(5);
  });

  test("add: -1 + 1 = 0", () => {
    expect(add(-1, 1)).toBe(0);
  });

  test("multiply: 2 * 3 = 6", () => {
    expect(multiply(2, 3)).toBe(6);
  });

  test("multiply: 0 * 100 = 0", () => {
    expect(multiply(0, 100)).toBe(0);
  });

  test("divide: 6 / 2 = 3", () => {
    expect(divide(6, 2)).toBe(3);
  });

  test("divide by zero throws error", () => {
    expect(() => divide(10, 0)).toThrow("Division by zero");
  });
});

テストを実行:

bun test

TypeScript のテストが追加設定なしで、高速に実行されます。


 6 pass
 0 fail
 6 expect() calls
Ran 6 tests across 1 file. [87.00ms]

Watch モードでのテスト

bun test --watch

ファイルの変更を監視して、自動的にテストを再実行します。

ファイル操作

Bun は高速なファイル I/O API を提供します。

file-operations.ts
// ファイルの読み込み
const file = Bun.file("package.json");
const text = await file.text();
console.log(text);

// JSON として読み込み
const json = await file.json();
console.log(`Project name: ${json.name}`);

// ファイルへの書き込み
await Bun.write("output.txt", "Hello, Bun!");
await Bun.write("data.json", JSON.stringify({ message: "Hello" }));

// バッファとして読み込み
const buffer = await file.arrayBuffer();
console.log(`File size: ${buffer.byteLength} bytes`);

// ファイルの存在確認
const exists = await file.exists();
console.log(`File exists: ${exists}`);

Node.js の fs モジュールと比較して、シンプルで高速な API です。

環境変数の管理

Node.js で .env ファイルを読み込むには、dotenv パッケージをインストールし、エントリーポイントで require('dotenv').config() を呼び出す必要があります(Node.js v20.6.0 以降では --env-file フラグでも可能)。

Bun は .env ファイルを自動的に読み込みます。追加のパッケージもコードの変更も不要です。

.env
DATABASE_URL=postgresql://localhost:5432/mydb
API_KEY=your-secret-key
PORT=3000
NODE_ENV=development
env-example.ts
// .env ファイルが自動的に読み込まれる
console.log(`Database URL: ${process.env.DATABASE_URL}`);
console.log(`API Key: ${process.env.API_KEY}`);
console.log(`Port: ${process.env.PORT}`);
console.log(`Environment: ${process.env.NODE_ENV}`);

// Bun.env でもアクセス可能
console.log(`Port via Bun.env: ${Bun.env.PORT}`);

実行:

bun run env-example.ts

dotenv パッケージのインストールは不要です。

SQLite データベース

Node.js で SQLite を使う場合、better-sqlite3sql.js といった外部パッケージのインストールが必要で、ネイティブモジュールのビルドに失敗するトラブルも少なくありません。

Bun は SQLite をネイティブサポートしており、bun:sqlite モジュールから外部パッケージなしで使えます。API は better-sqlite3 に近い同期的なインターフェースで、使い慣れた開発者にとっても移行しやすい設計です。

database.ts
import { Database } from "bun:sqlite";

// データベースを開く(存在しない場合は作成される)
const db = new Database("mydb.sqlite");

// テーブルの作成
db.run(`
  CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT UNIQUE NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
  )
`);

// プリペアドステートメントでデータ挿入
const insert = db.prepare("INSERT INTO users (name, email) VALUES (?, ?)");
insert.run("Alice", "alice@example.com");
insert.run("Bob", "bob@example.com");
insert.run("Charlie", "charlie@example.com");

// 全データの取得
const query = db.prepare("SELECT * FROM users");
const users = query.all();
console.log("All users:", users);

// 単一行の取得
const user = db.prepare("SELECT * FROM users WHERE name = ?").get("Alice");
console.log("Found user:", user);

// 条件付き検索
const searchEmail = db.prepare("SELECT * FROM users WHERE email LIKE ?");
const results = searchEmail.all("%example.com");
console.log("Users with example.com email:", results);

// データベースを閉じる
db.close();

実行:

bun run database.ts

高速で型安全な SQLite 操作が可能です。

バンドラー

フロントエンドのビルドには従来 webpack、Vite(内部で esbuild / Rollup を使用)、esbuild といったバンドラーが使われてきました。それぞれ設定ファイル(webpack.config.jsvite.config.ts など)の記述が必要です。

Bun にはビルトインのバンドラーがあり、CLI コマンド一つでバンドルを実行できます。内部的には esbuild と互換性のある API 設計で、ミニファイやソースマップ生成も標準サポートしています。webpack のような高度なプラグインエコシステムは持ちませんが、シンプルなプロジェクトであれば設定ファイルなしで十分に対応できます。

基本的なバンドル

src/greeting.ts
export function greeting(name: string): string {
  return `Hello, ${name}!`;
}

export function farewell(name: string): string {
  return `Goodbye, ${name}!`;
}
src/index.ts
import { greeting, farewell } from "./greeting";

console.log(greeting("World"));
console.log(farewell("World"));

バンドルを実行:

bun build src/index.ts --outdir ./dist

dist ディレクトリに最適化されたバンドルファイルが生成されます。

ミニファイとソースマップ

# ミニファイ(圧縮)
bun build src/index.ts --outdir ./dist --minify

# ソースマップ生成
bun build src/index.ts --outdir ./dist --sourcemap=external

# 両方を適用
bun build src/index.ts --outdir ./dist --minify --sourcemap=external

本番環境向けビルド

# ターゲット指定
bun build src/index.ts --outdir ./dist --target=browser

# Node.js向け
bun build src/index.ts --outdir ./dist --target=node

スクリプトの実行

package.json の scripts を実行

package.json
{
  "name": "my-project",
  "scripts": {
    "dev": "bun --watch src/server.ts",
    "build": "bun build src/index.ts --outdir ./dist --minify",
    "test": "bun test",
    "start": "bun run dist/index.js"
  }
}

実行:

bun run dev
bun run build
bun run test
bun run start

または短縮形:

bun dev
bun build
bun test
bun start

まとめ

Bun を使うことで、JavaScript/TypeScript 開発環境を大幅に高速化し、シンプル化できます。

従来の Node.js 開発では、ランタイム(Node.js)、パッケージマネージャー(npm / yarn)、バンドラー(webpack / Vite)、テストランナー(Jest / Vitest)、TypeScript 実行(ts-node)と、それぞれ個別のツールを導入・設定する必要がありました。Bun はこれらを一つのバイナリに統合し、設定ファイルの量とツール間の互換性問題を大幅に削減します。

主なポイントは以下の通りです。

  • Node.js より圧倒的に高速な実行とパッケージ管理
  • TypeScript、JSX のネイティブサポート(設定不要)
  • ビルトインのテストランナー、バンドラー
  • SQLite、Web API のネイティブ実装
  • Node.js との高い互換性(既存プロジェクトをそのまま移行可能)
  • シンプルで統一された API
  • 開発体験の大幅な向上

Bun は小規模なスクリプトから大規模なアプリケーションまで、幅広く活用できる次世代の JavaScript ランタイムです。既存の Node.js プロジェクトの移行も容易で、npm パッケージがそのまま使えるため、学習コストを抑えながらパフォーマンスの向上を実感できます。

特に以下のような場面で威力を発揮します。

  • 高速な開発サイクルを求めるプロジェクト
  • パフォーマンスが重要なサーバーサイドアプリケーション
  • TypeScript を多用するプロジェクト
  • 頻繁にパッケージをインストール・更新するプロジェクト
  • テストを頻繁に実行する開発フロー

参考

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?