- Framework: Next.js
- Deployment: Vercel
- Styling: Tailwind CSS
- Analytics: Vercel Analytics
git clone https://github.com/ryanwaits/site.git
cd site
bun install
bun devThe site includes an AI agent console (press A to toggle) powered by the Claude Agent SDK.
The Agent SDK requires Claude Code CLI installed. Vercel's serverless functions are stateless and can't install global packages, so we use Vercel Sandbox as a workaround:
Browser
↓
Next.js API Route (serverless)
↓
Vercel Sandbox (container with Claude Code CLI)
↓
agent-runner.js calls Agent SDK query()
↓
Streams JSON to stdout → parsed by API route → SSE to browser
Key files:
app/api/chat/route.ts- Main chat endpointapp/api/chat/sandbox.ts- Sandbox creation/reuse logicapp/api/chat/warmup/route.ts- Pre-warms sandbox when console opensapp/components/sandbox-boot.tsx- ASCII boot animation during cold start
Tradeoffs:
- Cold start: ~10-15s when sandbox needs to boot
- Session reuse: Sandbox persists for 5 min idle, reused via cookies
- Complexity: agent-runner.js glue needed since sandbox API is command-based
Required env vars (Vercel dashboard):
ANTHROPIC_API_KEY=sk-ant-...
VERCEL_TOKEN=...
VERCEL_TEAM_ID=...
VERCEL_PROJECT_ID=...
To eliminate the sandbox complexity and cold starts, deploy to a traditional server (Fly.io, Railway, Render, etc.):
# On the server
npm install -g @anthropic-ai/claude-code
next build && next startThen simplify the API route to call the SDK directly:
// app/api/chat/route.ts (simplified)
import { query } from '@anthropic-ai/claude-agent-sdk'
export async function POST(req: Request) {
const { message } = await req.json()
const stream = new ReadableStream({
async start(controller) {
const q = query({
prompt: message,
options: {
model: 'claude-sonnet-4-20250514',
systemPrompt: SYSTEM_PROMPT,
maxTurns: 3,
allowedTools: ['Read', 'Skill'],
},
})
for await (const msg of q) {
controller.enqueue(`data: ${JSON.stringify(msg)}\n\n`)
}
controller.close()
},
})
return new Response(stream, {
headers: { 'Content-Type': 'text/event-stream' },
})
}Files to delete if switching:
app/api/chat/sandbox.tsapp/api/chat/warmup/route.tsapp/components/sandbox-boot.tsx
Tradeoffs:
| Vercel + Sandbox | Traditional Server | |
|---|---|---|
| Cold start | ~10-15s | None |
| Ops | Zero | Some (deploys, scaling) |
| Cost | Per request + sandbox | Per uptime (~$5/mo) |
| Complexity | Higher | Lower |
- You are free to use this code as inspiration.
- Please do not copy it directly.
- Crediting the author is appreciated.