mcpField
B
bun-nextjs

bun-nextjs

github.com/secondsky開発240351 回インストール5 週間前に更新
リポジトリ

bun-nextjs について

bun-nextjs は、Bun を使う Next.js 開発者向けのスキルです。開発やビルド、ランタイム設定、Bun API の利用、安全な依存関係の導入方法を扱います。

主な機能

  1. 01Bun で Next.js を実行
  2. 02開発・ビルド・起動スクリプトの設定
  3. 03サーバーでの Bun API 利用
  4. 04依存関係の安全な導入
  5. 05デプロイと一般的なエラーの確認

活用シーン

  1. 01Next.js プロジェクトの作成と起動
  2. 02サーバーコンポーネントや API ルートで bun:sqlite を利用
  3. 03依存関係の導入に関する安全設定の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/secondsky/claude-skills --skill bun-next.js

インストール後、Claude Code で/bun-next.jsを入力して読み込まれたか確認します。

詳細

Bun Next.js

Bun を使用して、Next.js アプリケーションをより高速に開発・ビルドします。

クイックスタート

# Create new Next.js project with Bun
bunx create-next-app@latest my-app
cd my-app

# Install dependencies
bun install

# Development
bun run dev

# Build
bun run build

# Production
bun run start

セキュアなインストール

bunx create-next-app のようなスキャフォールディングツールは、リモートコードをダウンロードして実行します。ローカルや Docker など、複数のインストール環境では、それぞれでバージョンを固定する必要があります。実行する前に、次のサプライチェーンセキュリティのベストプラクティスに従ってください。

  • インストール後のスクリプトをブロックする — Bun ではデフォルトで無効になっています。package.json の trustedDependencies を使って、特定のパッケージを許可してください
  • クールダウン期間を設ける — bunfig.toml の minimumReleaseAge を設定し、新しいバージョンがリリースされてから 7 日間待つようにしてください
  • インストール前に監査する — socket package score npm <pkg> を実行するか、socket npm install <pkg> を使ってパッケージを確認してください

Socket CLI の統合、クールダウンの設定、ロックファイルの検証、CI での適用など、セキュリティ設定の全容については、dependency-upgrade スキルを読み込んでください。

プロジェクトのセットアップ

package.json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "eslint ."
  },
  "dependencies": {
    "next": "^16.2.0",
    "react": "^19.2.0",
    "react-dom": "^19.2.0"
  }
}
Bun をランタイムとして使う
{
  "scripts": {
    "dev": "bun --bun next dev",
    "build": "bun --bun next build",
    "start": "bun --bun next start"
  }
}

--bun フラグを指定すると、Next.js は Node.js ではなく Bun のランタイムを使用します。

設定

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  // Turbopack is the default bundler in Next.js 16 (top-level, not under experimental)
  turbopack: {},

  // Server-side Bun APIs
  serverExternalPackages: ["bun:sqlite"],

  // Note: a `webpack` key is no longer supported in Next.js 16 — Turbopack is the
  // default bundler and a `webpack` config will fail `next build`. Bun-specific
  // imports (`bun:sqlite`, `bun:ffi`) are handled via `serverExternalPackages`
  // above. If you truly need the webpack bundler, run `next build --webpack`.
};

module.exports = nextConfig;

Next.js で Bun API を使う

サーバーコンポーネント
// app/page.tsx (Server Component)
import { Database } from "bun:sqlite";

export default async function Home() {
  const db = new Database("data.sqlite");
  const users = db.query("SELECT * FROM users").all();
  db.close();

  return (
    <div>
      {users.map((user) => (
        <p key={user.id}>{user.name}</p>
      ))}
    </div>
  );
}
API ルート
// app/api/users/route.ts
import { Database } from "bun:sqlite";

export async function GET() {
  const db = new Database("data.sqlite");
  const users = db.query("SELECT * FROM users").all();
  db.close();

  return Response.json(users);
}

export async function POST(request: Request) {
  const body = await request.json();

  const db = new Database("data.sqlite");
  db.run("INSERT INTO users (name) VALUES (?)", [body.name]);
  db.close();

  return Response.json({ success: true });
}
ファイル操作
// app/api/files/route.ts
export async function GET() {
  const file = Bun.file("./data/config.json");
  const config = await file.json();

  return Response.json(config);
}

export async function POST(request: Request) {
  const data = await request.json();
  await Bun.write("./data/config.json", JSON.stringify(data, null, 2));

  return Response.json({ saved: true });
}

サーバーアクション

// app/actions.ts
"use server";

import { Database } from "bun:sqlite";
import { revalidatePath } from "next/cache";

export async function createUser(formData: FormData) {
  const name = formData.get("name") as string;

  const db = new Database("data.sqlite");
  db.run("INSERT INTO users (name) VALUES (?)", [name]);
  db.close();

  revalidatePath("/users");
}

export async function deleteUser(id: number) {
  const db = new Database("data.sqlite");
  db.run("DELETE FROM users WHERE id = ?", [id]);
  db.close();

  revalidatePath("/users");
}

プロキシ(旧ミドルウェア)

Next.js 16 では、middleware.ts の名前が proxy.ts に変更されました(middleware という名前も引き続き動作しますが、非推奨です)。プロキシは Edge ランタイムではなく、Node.js ランタイムで実行されます。

⚠️ OpenNext 経由で Cloudflare にデプロイしますか?middleware.ts を使い続けてください。 @opennextjs/cloudflare は、まだ proxy.ts というファイル名を認識しません。名前を変更すると、Cloudflare 上でミドルウェアが通知なく無効になります。 OpenNext にサポートが追加されるまでは、従来の middleware.ts を使ってデプロイしてください(Next 16 でも動作しますが、上流では非推奨です)。 この注意点は、Node.js、Vercel、Bun ネイティブのデプロイには当てはまりません。

// proxy.ts (renamed from middleware.ts in Next.js 16)
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export function proxy(request: NextRequest) {
  // Check auth
  const token = request.cookies.get("token");

  if (!token && request.nextUrl.pathname.startsWith("/dashboard")) {
    return NextResponse.redirect(new URL("/login", request.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: ["/dashboard/:path*"],
};

環境変数

# .env.local
DATABASE_URL=./data.sqlite
API_SECRET=your-secret-key
// Access in server components/actions
const dbUrl = process.env.DATABASE_URL;
const secret = process.env.API_SECRET;

// Expose to client (prefix with NEXT_PUBLIC_)
// .env.local
NEXT_PUBLIC_API_URL=https://api.example.com

デプロイ

本番環境向けビルド
bun run build
bun run start
Docker
FROM oven/bun:1

WORKDIR /app

COPY package.json bun.lockb ./
RUN bun install --frozen-lockfile

COPY . .
RUN bun run build

EXPOSE 3000

CMD ["bun", "run", "start"]
Vercel
# Install Vercel CLI
bun add -g vercel

# Deploy
vercel

注:Vercel の Edge ランタイムでは Bun ではなく V8 が使われます。Bun API は次の環境で動作します。

  • サーバーコンポーネント(Node.js ランタイム)
  • API ルート(Node.js ランタイム)
  • サーバーアクション(Node.js ランタイム)

パフォーマンスのヒント

  1. Next.js 16 では Turbopack がデフォルトです(フラグは不要です)。

    bun run dev
    
  2. サーバーコンポーネントを優先してください - クライアントに送信される JavaScript を減らせます

  3. シンプルなアプリでは、外部データベースの代わりに Bun SQLite を使ってください

  4. 圧縮を有効にしてください。

    // next.config.js
    module.exports = {
      compress: true,
    };
    

よくあるエラー

エラー原因対処法
Cannot find bun:sqliteランタイムが違いますbun --bun next dev を使ってください
Module not found依存関係が不足していますbun install を実行してください
Hydration mismatchサーバーとクライアントの差異データ取得を確認してください
Edge runtime errorEdge 上での Bun API の使用Node.js ランタイムを使ってください

リファレンスを読み込むタイミング

次の場合は references/app-router.md を読み込んでください。

  • App Router のパターン
  • ルートグループ
  • 並列ルート

次の場合は references/caching.md を読み込んでください。

  • データキャッシュ戦略
  • 再検証のパターン
  • 静的生成

コメント