bun-nextjs について
bun-nextjs は、Bun を使う Next.js 開発者向けのスキルです。開発やビルド、ランタイム設定、Bun API の利用、安全な依存関係の導入方法を扱います。
主な機能
- 01Bun で Next.js を実行
- 02開発・ビルド・起動スクリプトの設定
- 03サーバーでの Bun API 利用
- 04依存関係の安全な導入
- 05デプロイと一般的なエラーの確認
活用シーン
- 01Next.js プロジェクトの作成と起動
- 02サーバーコンポーネントや API ルートで bun:sqlite を利用
- 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 ランタイム)
パフォーマンスのヒント
-
Next.js 16 では Turbopack がデフォルトです(フラグは不要です)。
bun run dev -
サーバーコンポーネントを優先してください - クライアントに送信される JavaScript を減らせます
-
シンプルなアプリでは、外部データベースの代わりに Bun SQLite を使ってください
-
圧縮を有効にしてください。
// next.config.js module.exports = { compress: true, };
よくあるエラー
| エラー | 原因 | 対処法 |
|---|---|---|
Cannot find bun:sqlite | ランタイムが違います | bun --bun next dev を使ってください |
Module not found | 依存関係が不足しています | bun install を実行してください |
Hydration mismatch | サーバーとクライアントの差異 | データ取得を確認してください |
Edge runtime error | Edge 上での Bun API の使用 | Node.js ランタイムを使ってください |
リファレンスを読み込むタイミング
次の場合は references/app-router.md を読み込んでください。
- App Router のパターン
- ルートグループ
- 並列ルート
次の場合は references/caching.md を読み込んでください。
- データキャッシュ戦略
- 再検証のパターン
- 静的生成