Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Deploying a Full-Stack Bun-Native Framework on ...

Avatar for daiki7nohe daiki7nohe
September 10, 2026

Deploying a Full-Stack Bun-Native Framework on Cloudflare Workers

Cloudflare Workers Tech Talks in Fukuoka #2
https://workers-tech.connpass.com/event/401855/

Avatar for daiki7nohe

daiki7nohe

September 10, 2026

More Decks by daiki7nohe

Other Decks in Technology

Transcript

  1. CLOUDFLARE WORKERS TECH TALKS IN FUKUOKA #2 / 2026/09/10 Deploying

    a Full-Stack Bun-Native Framework on Cloudflare Workers 浦田 大貴 X: @daiki7nohe/GitHub: @7nohe $ bunx wrangler deploy
  2. 00 / 自己紹介 浦田 大貴 X: @daiki7nohe 株式会社Fusic OSSでフルスタックTypeScriptフレームワーク Guren

    を作っています docs guren.dev Guren / Cloudflare Workers Tech Talks in Fukuoka #2 code github.com/7nohe/gurenjs 02 / 20
  3. AGENDA / 話 すこと 今日話すこと 01 前回 (Containers 編) からの続き

    5 min 02 なぜ Workers 本体を選んだか 3 min 03 workerd で動かすということ 5 min 04 ビルドの罠 5 min 05 まとめ 2 min Guren / Cloudflare Workers Tech Talks in Fukuoka #2 03 / 20
  4. 01 / 前 回 から の 続 き 2025-11 /

    containers 前回: Bunアプリを Containersで動かす 2026-09 / workers 今回: Bun向けFWを Workersに対応させる Guren / Cloudflare Workers Tech Talks in Fukuoka #2 speakerdeck.com/7nohe/deploying-full-stackbun-applications-on-cloudflare 04 / 20
  5. INTRO / G U R E N とは MVCパターンのフルスタック TypeScript

    フレームワーク Guren mvc controller model view docs guren.dev 層は Guren、中身は既存のライブラリ Hono ルーティングとミドルウェア。 Request / Response は Web 標準 Drizzle スキーマとクエリ。 SQLite 方言で書けば D1 でもそのまま動く React + Inertia コントローラが渡した props をそのまま描画。 REST 層を挟まない Guren / Cloudflare Workers Tech Talks in Fukuoka #2 05 / 20
  6. I N T R O / コ ード例 GET /POSTS

    ルート定義から React の props まで、 型が繋がる routes/web.ts export function registerWebRoutes( PostController.ts async index() { router: Router) { pages/posts/Index.tsx type Props = PageProps< const { page } = this router.get('/posts', typeof pages.posts.Index> .validateQuery(ListPostsQuery) [PostController, 'index']) const { data } = await Post router.post('/posts', export default function Index( .paginate({ page, perPage: 20 }) [PostController, 'store']) { data }: Props) { return this.inertia( } pages.posts.Index, { data }) return <PostList posts={data} /> } } RULE APIクライアントも書かない。InertiaがコントローラのpropsをそのままReactに渡す。 Guren / Cloudflare Workers Tech Talks in Fukuoka #2 06 / 20
  7. 02 / 選択 動機は 「デプロイ先を増やす」 GurenはもともとBun専用のフレームワークとして開発していた デプロイの選択肢を増やしたかった Guren on Hono

    Cloudflare Workers 今日の話 / D1 Vercel Hono adapter AWS Lambda / その他 Guren / Cloudflare Workers Tech Talks in Fukuoka #2 Hono adapter 次第 07 / 20
  8. 罠 / WORKERD 1 workerd で 動かすということ V8 isolate は

    Node でも Bun でもない。 まず実行モデルが違う Guren / Cloudflare Workers Tech Talks in Fukuoka #2 08 / 20
  9. 03 / 実 行 モ デル トップレベルで I/O を発行できない Bun

    ならこう書ける // module scope Workers ではリクエスト内へ export default { const db = connect("…") // ← I/O async fetch(req, env) { const db = boot(env.DB) // ここ await migrate(db) } } RULE workerd が global scope での I/O 発行そのものを禁じている。 Guren / Cloudflare Workers Tech Talks in Fukuoka #2 09 / 20
  10. 03 / BUN.PASSWORD workerd に Bun.password は無い before / bun

    const hash = await Bun.password .hash(pw) // argon2id after / node:crypto // nodejs_compat。 scrypt は Workers でも使える const hash = await scryptHash(pw) // $scrypt$… はどこでも検証できる形式 await Bun.password.verify(pw, hash) RULE node:crypto は Workers でもほぼ全部使えるが argon2。 差し替えれば動くが、 コストは CPU 側に移る。 Guren / Cloudflare Workers Tech Talks in Fukuoka #2 10 / 20
  11. 03 / BUN.FILE public/ の静的ファイルは、Worker の中で 配るのをやめて、 Static Assets に任せた。

    before / bun after / assets + r2 const f = Bun.file("public/og.png") // 静的配信は assets binding return new Response(f) return env.ASSETS.fetch(req) Guren / Cloudflare Workers Tech Talks in Fukuoka #2 11 / 20
  12. 03 / 移 植 し な かった も の 意外と手を加えることは少なかった

    書 き直した 触って い な い → リクエスト内) 静的ファイルの置き場所 (アプリ配信 → プラットフォーム 起動のタイミング (module scope 配信) 接続の作り方 (new Database() RULE → env.DB) ルーティング、 ミドルウェア、Cookie、ヘッダ (Hono) db/schema.ts とクエリ (Drizzle、 SQLite 方言のまま) コントローラ、 バリデーション、ページ Workers アダプタの本体は 33 行で済んだ。 Guren / Cloudflare Workers Tech Talks in Fukuoka #2 12 / 20
  13. 04 / BUILD import.meta.url使えない問題 src/runtime/paths.ts const url = new URL("./foo.txt",

    import.meta.url) // import.meta.url が undefined → 起動時に例外 // 解決: ビルド時に嘘の値を埋める "define": { "import.meta.url": "\"file:///worker.js\"" } Guren / Cloudflare Workers Tech Talks in Fukuoka #2 14 / 20
  14. 04 / BUILD 2026-09-09 CLOUDFLARE BLOG この回避は、 直る予定です workerd のモジュールレジストリが書き直され、specifier

    を URL として解決す るようになった。 フラグ 1 行で有効になる。 wrangler.jsonc 01 import.meta.url / .main / .resolve() が動く 02 相対 import が new URL(spec, base) と同じ規 則で解決される { "compatibility_flags": ["new_module_registry"] } デフォルトで有効になる日付はまだ無い。明示的に足す必要がある。 Guren / Cloudflare Workers Tech Talks in Fukuoka #2 03 モジュールは初回 import 時に遅延コンパイル、 コードキャッシュも共有 blog.cloudflare.com/workers-module-registrynodejs/ 15 / 20
  15. 04 / BUNDLER ローカルで動いて、 バンドル時に落ちる src/db/client.ts if (isDev) { const

    db = await import('bun:sqlite') } // ✘ Could not resolve "bun:sqlite" Guren / Cloudflare Workers Tech Talks in Fukuoka #2 16 / 20
  16. 04 / ALIAS aliasで解決 wrangler.jsonc "alias": { "bun:sqlite": "./stub-bun-sqlite.js", "postgres":

    "./stub-postgres.js", "mysql2": "./stub-mysql2.js" } 箱は揃うので荷造りは通る。 実行されないので中身は要らない。 Guren / Cloudflare Workers Tech Talks in Fukuoka #2 17 / 20
  17. 05 / 運用 GUREN.DEV guren.dev 自体も Workers の上で動いていて、 運用費は月 0

    円 CLOUDFLARE Static Assets HTTPS ブラウザ / エージェント docs の JSON 断⽚ / .md / llms-full.txt / public Worker より先に応答する SQL D1 posts / users / sessions 検索索引 (FTS5) ASSETS.fetch() Worker Guren / Hono / SSR Analytics Engine boot は最初のリクエスト内 (global scope の I/O 禁⽌) Guren / Cloudflare Workers Tech Talks in Fukuoka #2 18 / 20
  18. 05 / まとめ Workers で動いて、 こう変わった 01 デプロイ先の選択肢が増えた Bun を動かせるホストを探す必要がなくなり、bunx

    wrangler deploy だけで本番に出せる。 02 Cloudflare のマネージドをそのまま使える D1 をバインディングから、静的ファイルは static assets から。 DB もホスティングも自前で用意しなくてよくなった。 03 フレームワーク自体が、標準寄りになった Bun 前提を剥がした結果、Hono / Drizzle / Web 標準で組み直せた。 Vercel など他のアダプタも同じ延長線上に載る。 Guren / Cloudflare Workers Tech Talks in Fukuoka #2 19 / 20
  19. THANKS / QUESTIONS ありがとう ございました $ bunx create-guren-app my-app docs

    guren.dev Guren / Cloudflare Workers Tech Talks in Fukuoka #2 code github.com/7nohe/gurenjs 20 / 20