Documentation Index Fetch the complete documentation index at: https://docs.buntime.sh/llms.txt
Use this file to discover all available pages before exploring further.
Overview
buntime.sh makes it easy to build and preview web applications. Every session gets a unique preview URL, and Bun 1.3’s built-in hot module reloading (HMR) automatically updates your app when code changes.
Quick Start
Create a Simple Server
import { Buntime } from 'buntime.sh' ;
const client = new Buntime ({ apiKey: process . env . BUNTIME_API_KEY });
// Create a session
const session = await client . sessions . create ();
// Write a simple server
await client . files . write ({
sessionId: session . id ,
path: 'server.ts' ,
content: `
Bun.serve({
port: 8080,
fetch(req) {
return new Response("Hello from buntime!");
}
});
console.log("Server running on port 8080");
`
});
// Start the server
await client . execute ({
sessionId: session . id ,
command: 'bun run server.ts'
});
// Your app is live at:
console . log ( `Preview URL: https:// ${ session . id } .buntime.sh` );
Preview URLs
Every session gets a unique subdomain:
https://{sessionId}.buntime.sh
Key features:
✅ Always uses port 8080 (required)
✅ HTTPS enabled by default
✅ Proxied through Cloudflare for security
✅ Stays active as long as the session exists
✅ No configuration needed
Your web server must listen on port 8080. Other ports are not accessible via the preview URL.
Hot Module Reloading
Bun 1.3 includes built-in HMR that works automatically:
// Write initial server
await client . files . write ({
sessionId: session . id ,
path: 'app.ts' ,
content: `
Bun.serve({
port: 8080,
fetch(req) {
return new Response("Version 1");
}
});
`
});
// Start the server
await client . execute ({
sessionId: session . id ,
command: 'bun --hot app.ts' // Enable hot reload
});
// Update the code - HMR automatically reloads!
await client . files . write ({
sessionId: session . id ,
path: 'app.ts' ,
content: `
Bun.serve({
port: 8080,
fetch(req) {
return new Response("Version 2 - Updated!");
}
});
`
});
// Visit preview URL - changes are live instantly
Use the --hot flag when starting your server to enable automatic hot reloading.
Static HTML
You can serve static HTML directly with Bun:
await client . files . write ({
sessionId: session . id ,
path: 'index.html' ,
content: `
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
<style>
body {
font-family: system-ui;
max-width: 800px;
margin: 50px auto;
padding: 20px;
}
</style>
</head>
<body>
<h1>Hello from buntime.sh!</h1>
<p>This is a static HTML page.</p>
</body>
</html>
`
});
await client . files . write ({
sessionId: session . id ,
path: 'server.ts' ,
content: `
Bun.serve({
port: 8080,
async fetch(req) {
const url = new URL(req.url);
const path = url.pathname === '/' ? '/index.html' : url.pathname;
try {
const file = Bun.file('.' + path);
return new Response(file);
} catch {
return new Response('Not Found', { status: 404 });
}
}
});
`
});
await client . execute ({
sessionId: session . id ,
command: 'bun --hot server.ts'
});
React Application
Build a full React app with JSX support:
// Write React component
await client . files . write ({
sessionId: session . id ,
path: 'App.tsx' ,
content: `
import { useState } from 'react';
export function App() {
const [count, setCount] = useState(0);
return (
<div style={{ fontFamily: 'system-ui', padding: '50px' }}>
<h1>React + buntime.sh</h1>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</div>
);
}
`
});
// Write server with React rendering
await client . files . write ({
sessionId: session . id ,
path: 'server.tsx' ,
content: `
import { renderToReadableStream } from 'react-dom/server';
import { App } from './App';
Bun.serve({
port: 8080,
async fetch(req) {
const stream = await renderToReadableStream(<App />);
return new Response(stream, {
headers: { 'Content-Type': 'text/html' }
});
}
});
console.log('React app running on port 8080');
`
});
// Install React (Bun auto-installs on import, but explicit install is faster)
await client . execute ({
sessionId: session . id ,
command: 'bun add react react-dom'
});
// Start the server
await client . execute ({
sessionId: session . id ,
command: 'bun --hot server.tsx'
});
API Routes
Create a JSON API:
await client . files . write ({
sessionId: session . id ,
path: 'api.ts' ,
content: `
interface User {
id: number;
name: string;
email: string;
}
const users: User[] = [
{ id: 1, name: 'Alice', email: '[email protected] ' },
{ id: 2, name: 'Bob', email: '[email protected] ' }
];
Bun.serve({
port: 8080,
fetch(req) {
const url = new URL(req.url);
// GET /api/users
if (url.pathname === '/api/users' && req.method === 'GET') {
return Response.json(users);
}
// GET /api/users/:id
const userMatch = url.pathname.match(/^ \/ api \/ users \/ ( \d +)$/);
if (userMatch && req.method === 'GET') {
const id = parseInt(userMatch[1]);
const user = users.find(u => u.id === id);
if (user) {
return Response.json(user);
}
return Response.json({ error: 'User not found' }, { status: 404 });
}
// POST /api/users
if (url.pathname === '/api/users' && req.method === 'POST') {
const body = await req.json();
const newUser = {
id: users.length + 1,
name: body.name,
email: body.email
};
users.push(newUser);
return Response.json(newUser, { status: 201 });
}
return Response.json({ error: 'Not found' }, { status: 404 });
}
});
console.log('API server running on port 8080');
`
});
await client . execute ({
sessionId: session . id ,
command: 'bun --hot api.ts'
});
WebSocket Server
Build real-time apps with WebSockets:
await client . files . write ({
sessionId: session . id ,
path: 'websocket.ts' ,
content: `
const clients = new Set();
Bun.serve({
port: 8080,
fetch(req, server) {
const url = new URL(req.url);
// WebSocket upgrade
if (url.pathname === '/ws') {
const upgraded = server.upgrade(req);
if (!upgraded) {
return new Response('WebSocket upgrade failed', { status: 400 });
}
return undefined;
}
// Serve HTML client
return new Response( \`
<!DOCTYPE html>
<html>
<body>
<h1>WebSocket Chat</h1>
<div id="messages"></div>
<input id="input" type="text" placeholder="Type a message..." />
<button onclick="send()">Send</button>
<script>
const ws = new WebSocket('wss://' + location.host + '/ws');
const messages = document.getElementById('messages');
const input = document.getElementById('input');
ws.onmessage = (e) => {
const p = document.createElement('p');
p.textContent = e.data;
messages.appendChild(p);
};
function send() {
ws.send(input.value);
input.value = '';
}
input.addEventListener('keypress', (e) => {
if (e.key === 'Enter') send();
});
</script>
</body>
</html>
\` , {
headers: { 'Content-Type': 'text/html' }
});
},
websocket: {
open(ws) {
clients.add(ws);
console.log('Client connected. Total:', clients.size);
},
message(ws, message) {
// Broadcast to all clients
for (const client of clients) {
client.send(message);
}
},
close(ws) {
clients.delete(ws);
console.log('Client disconnected. Total:', clients.size);
}
}
});
console.log('WebSocket server running on port 8080');
`
});
await client . execute ({
sessionId: session . id ,
command: 'bun --hot websocket.ts'
});
File Uploads
Handle file uploads:
await client . files . write ({
sessionId: session . id ,
path: 'upload.ts' ,
content: `
Bun.serve({
port: 8080,
async fetch(req) {
const url = new URL(req.url);
// Serve upload form
if (url.pathname === '/' && req.method === 'GET') {
return new Response( \`
<!DOCTYPE html>
<html>
<body>
<h1>File Upload</h1>
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="file" required />
<button type="submit">Upload</button>
</form>
</body>
</html>
\` , {
headers: { 'Content-Type': 'text/html' }
});
}
// Handle file upload
if (url.pathname === '/upload' && req.method === 'POST') {
const formData = await req.formData();
const file = formData.get('file') as File;
if (!file) {
return Response.json({ error: 'No file provided' }, { status: 400 });
}
// Save file
await Bun.write( \` uploads/ \$ {file.name} \` , file);
return Response.json({
message: 'File uploaded successfully',
filename: file.name,
size: file.size,
type: file.type
});
}
return new Response('Not Found', { status: 404 });
}
});
console.log('Upload server running on port 8080');
`
});
// Create uploads directory
await client . execute ({
sessionId: session . id ,
command: 'mkdir -p uploads'
});
await client . execute ({
sessionId: session . id ,
command: 'bun --hot upload.ts'
});
Environment Variables
Pass secrets and config to your web app:
await client . execute ({
sessionId: session . id ,
files: [
{
path: 'app.ts' ,
content: `
Bun.serve({
port: 8080,
fetch(req) {
return Response.json({
environment: process.env.NODE_ENV,
apiKey: process.env.API_KEY ? '***' : 'not set'
});
}
});
`
}
],
command: 'bun --hot app.ts' ,
env: {
NODE_ENV: 'production' ,
API_KEY: 'secret_key_123'
}
});
Enable CORS for external API access:
await client . files . write ({
sessionId: session . id ,
path: 'cors.ts' ,
content: `
Bun.serve({
port: 8080,
fetch(req) {
// Handle preflight
if (req.method === 'OPTIONS') {
return new Response(null, {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
}
});
}
// Handle actual request
const data = { message: 'Hello from CORS-enabled API' };
return Response.json(data, {
headers: {
'Access-Control-Allow-Origin': '*'
}
});
}
});
`
});
Debugging Tips
Check if server is running
List active processes to see if your server started: const info = await client . sessions . info ({ sessionId: session . id });
console . log ( 'Active processes:' , info . activeProcesses );
Execution output includes console.log from your server: const result = await client . execute ({
sessionId: session . id ,
command: 'bun run server.ts'
});
console . log ( 'Server output:' , result . stdout );
console . log ( 'Server errors:' , result . stderr );
Test your server code locally before deploying: bun run server.ts
# Visit http://localhost:8080
Kill the process and start fresh: await client . execution . kill ({ sessionId: session . id });
await client . execute ({
sessionId: session . id ,
command: 'bun --hot server.ts'
});
Limitations
Important limitations:
Only port 8080 is accessible via preview URL
Preview URLs require the session to be active
No custom domains (use the provided subdomain)
WebSocket connections close when session sleeps
Maximum 1 web server per session
Best Practices
Use --hot flag Enable hot reload for faster iteration during development
Handle errors Return proper error responses with status codes
Log to stdout Use console.log for debugging—output is captured in execute results
Test endpoints Verify your API routes work before sharing preview URLs
Examples
Express Server Full Express.js application
React SSR Server-side rendered React app
REST API Complete CRUD API example
WebSocket Chat Real-time chat application
Next Steps
Databases Add databases to your web app
Multi-file Projects Organize larger applications
Environment Variables Manage secrets and configuration
API Reference Explore execution options