Vercel Deployment#

BunTok supports zero-config deployment on Vercel with Bun runtime. Select "Yes" when prompted during buntok init to set up the clean entry point pattern.

How It Works#

BunTok uses a single server.ts entry point for all modes — local development and Vercel. The app.listen() method auto-detects the runtime: it calls Bun.serve() locally, and works seamlessly on Vercel serverless.

server.ts — universal entry point#

typescript
import { app } from "./src/index";
import { env } from "./src/env";

app.listen(env.PORT);

Why `app.listen()` Works Everywhere#

  • Local devapp.listen() calls Bun.serve() and binds to a port
  • Vercelapp.listen() detects the serverless environment and delegates to app.fetch() automatically
  • No separate entry points needed — one server.ts works for both

app.fetch() vs app.listen()#

MethodUse CaseBinds Port
app.listen(port)Local developmentYes
app.fetch(request)Vercel/serverlessNo
app.request(input, init?)TestingNo

vercel.json#

Generated by buntok init when Vercel is selected:

json
{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "framework": "bun",
  "bunVersion": "1.4.x"
}
  • framework: "bun" — tells Vercel to use Bun runtime (required for GitHub-triggered deploys).
  • bunVersion: "1.4.x" — pins the Bun runtime version.

Deploy#

bash
# Install Vercel CLI
npm i -g vercel

# Deploy (preview)
vercel

# Production deploy
vercel --prod

Local Development#

bash
bun run dev   # runs: bun --watch server.ts

The dev script runs server.ts which calls app.listen() — this is separate from the Vercel entry point.

Project Structure#

typescript
my-app/
├── src/
│   ├── index.ts              # export const app = new App()
│   ├── env.ts                # App.validateEnv({ PORT, ... })
│   ├── controllers/
│   ├── services/
│   └── repositories/
├── server.ts                 # app.listen(env.PORT) — universal entry point
├── vercel.json               # Vercel config (framework: "bun")
├── package.json
└── ...

Notes#

  • WebSocket routes may need additional Vercel configuration
  • For monorepos, set the Root Directory in Vercel dashboard to your project subfolder
Info
app.listen() is the universal entry point — it works for both local development and Vercel serverless. No special configuration needed.