Bun.serve Samples
Bun.serve web server examples including HTTP server, WebSocket, and static file serving
Key Facts
- Category
- Web Frameworks
- Items
- 4
- Format Families
- sample
Sample Overview
Bun.serve web server examples including HTTP server, WebSocket, and static file serving This sample set belongs to Web Frameworks and can be used to test related workflows inside Elysia Tools.
💻 Bun.serve Hello World typescript
🟢 simple
Basic Bun.serve HTTP server setup and Hello World application
// Bun.serve Hello World Examples
// 1. Basic HTTP server
const server1 = Bun.serve({
port: 3000,
fetch(req) {
return new Response("Hello, World!");
},
});
console.log(`Listening on http://localhost:${server1.port}...`);
// 2. Hello World with routing
const server2 = Bun.serve({
port: 3000,
fetch(req) {
const url = new URL(req.url);
switch (url.pathname) {
case '/':
return new Response('Hello, Bun!');
case '/hello':
return new Response('Hello from Bun.serve!');
default:
if (url.pathname.startsWith('/hello/')) {
const name = url.pathname.split('/')[2];
return new Response(`Hello, ${name}!`);
}
return new Response('Not Found', { status: 404 });
}
},
});
// 3. JSON response
const server3 = Bun.serve({
port: 3000,
fetch(req) {
const url = new URL(req.url);
if (url.pathname === '/api/hello') {
return Response.json({
message: 'Hello, World!',
timestamp: new Date().toISOString(),
version: '1.0.0',
runtime: 'Bun'
});
}
return new Response('Hello, World!');
},
});
// 4. HTTP methods handling
const server4 = Bun.serve({
port: 3000,
fetch(req) {
const url = new URL(req.url);
const method = req.method;
if (url.pathname === '/api/users') {
switch (method) {
case 'GET':
return Response.json(['Alice', 'Bob', 'Charlie']);
case 'POST':
return new Response('User created', { status: 201 });
default:
return new Response('Method Not Allowed', { status: 405 });
}
}
return new Response('Hello, World!');
},
});
// 5. Request body parsing
const server5 = Bun.serve({
port: 3000,
async fetch(req) {
const url = new URL(req.url);
if (url.pathname === '/api/hello' && req.method === 'POST') {
const body = await req.json();
return Response.json({
greeting: `Hello, ${body.name || 'World'}!`,
message: body.message || 'Welcome to Bun.serve',
receivedAt: new Date().toISOString()
});
}
return new Response('Hello, World!');
},
});
// 6. HTML response
const server6 = Bun.serve({
port: 3000,
fetch(req) {
const url = new URL(req.url);
if (url.pathname === '/') {
const html = `
<!DOCTYPE html>
<html>
<head>
<title>Hello Bun</title>
</head>
<body>
<h1>Hello, World!</h1>
<p>This is an HTML response from Bun.serve</p>
</body>
</html>
`;
return new Response(html, {
headers: { 'Content-Type': 'text/html' }
});
}
return new Response('Hello, World!');
},
});
// 7. Error handling
const server7 = Bun.serve({
port: 3000,
fetch(req) {
const url = new URL(req.url);
if (url.pathname === '/error') {
throw new Error('Something went wrong!');
}
return new Response('Hello, World!');
},
error(error) {
return new Response(`Error: ${error.message}`, { status: 500 });
},
});
// 8. Server information
const server8 = Bun.serve({
port: 3000,
fetch(req) {
const url = new URL(req.url);
if (url.pathname === '/info') {
return Response.json({
server: {
hostname: server8.hostname,
port: server8.port,
development: server8.development
},
request: {
method: req.method,
url: req.url,
headers: Object.fromEntries(req.headers.entries())
}
});
}
return new Response('Hello, World!');
},
});
console.log(`🦊 Bun server running at http://localhost:${server8.port}`);
💻 Bun.serve WebSocket Server typescript
🟡 intermediate
WebSocket server implementation using Bun.serve
// Bun.serve WebSocket Examples
// 1. Basic WebSocket server
const server = Bun.serve({
port: 3000,
fetch(req, server) {
const url = new URL(req.url);
if (url.pathname === '/ws') {
const upgraded = server.upgrade(req);
if (upgraded) {
return undefined; // WebSocket handled
}
}
return new Response('Not Found', { status: 404 });
},
websocket: {
message(ws, message) {
ws.send(`Echo: ${message}`);
},
open(ws) {
console.log('WebSocket connection opened');
ws.send('Welcome to Bun WebSocket server!');
},
close(ws) {
console.log('WebSocket connection closed');
},
},
});
// 2. Chat server
interface ChatMessage {
type: 'message' | 'join' | 'leave';
user: string;
content: string;
timestamp: string;
}
const clients = new Set<WebSocket>();
const server = Bun.serve({
port: 3000,
fetch(req, server) {
const url = new URL(req.url);
if (url.pathname === '/chat') {
const upgraded = server.upgrade(req);
if (upgraded) {
return undefined;
}
}
return new Response('Chat server running');
},
websocket: {
message(ws, message: string) {
const chatMessage: ChatMessage = {
type: 'message',
user: ws.data.userId || 'Anonymous',
content: message,
timestamp: new Date().toISOString()
};
// Broadcast to all clients
server.publish('chat', JSON.stringify(chatMessage));
},
open(ws) {
const userId = `user_${Math.random().toString(36).substr(2, 9)}`;
ws.data = { userId };
clients.add(ws);
ws.subscribe('chat');
const joinMessage: ChatMessage = {
type: 'join',
user: 'System',
content: `${userId} joined the chat`,
timestamp: new Date().toISOString()
};
server.publish('chat', JSON.stringify(joinMessage));
},
close(ws) {
clients.delete(ws);
ws.unsubscribe('chat');
const leaveMessage: ChatMessage = {
type: 'leave',
user: 'System',
content: `${ws.data.userId} left the chat`,
timestamp: new Date().toISOString()
};
server.publish('chat', JSON.stringify(leaveMessage));
},
},
});
// 3. Real-time notifications
const server = Bun.serve({
port: 3000,
fetch(req, server) {
const url = new URL(req.url);
if (url.pathname === '/notifications') {
const upgraded = server.upgrade(req);
if (upgraded) {
return undefined;
}
}
return new Response('Notification server running');
},
websocket: {
open(ws) {
console.log('Notification client connected');
ws.data.interval = setInterval(() => {
const notification = {
type: 'notification',
title: 'System Update',
message: `System time: ${new Date().toLocaleTimeString()}`,
timestamp: new Date().toISOString()
};
ws.send(JSON.stringify(notification));
}, 5000);
},
close(ws) {
if (ws.data.interval) {
clearInterval(ws.data.interval);
}
},
},
});
// 4. WebSocket with authentication
const server = Bun.serve({
port: 3000,
fetch(req, server) {
const url = new URL(req.url);
const auth = req.headers.get('authorization');
if (url.pathname === '/auth-ws') {
// Simple token validation
if (!auth?.startsWith('Bearer ') || auth.slice(7) !== 'valid-token') {
return new Response('Unauthorized', { status: 401 });
}
const upgraded = server.upgrade(req);
if (upgraded) {
return undefined;
}
}
return new Response('WebSocket server with authentication');
},
websocket: {
message(ws, message) {
ws.send(`Authenticated message: ${message}`);
},
open(ws) {
ws.send('WebSocket connection authenticated');
},
},
});
console.log(`🦊 Bun WebSocket server running at http://localhost:${server.port}`);
💻 Bun.serve Static File Server typescript
🟡 intermediate
Static file serving with caching and directory listing
// Bun.serve Static File Server Examples
// 1. Basic static file server
const server = Bun.serve({
port: 3000,
fetch(req) {
const url = new URL(req.url);
const filePath = url.pathname === '/' ? './public/index.html' : `./public${url.pathname}`;
try {
const file = Bun.file(filePath);
return new Response(file);
} catch (error) {
return new Response('File not found', { status: 404 });
}
},
});
// 2. Static file server with caching
const server = Bun.serve({
port: 3000,
fetch(req) {
const url = new URL(req.url);
const filePath = url.pathname === '/' ? './public/index.html' : `./public${url.pathname}`;
try {
const file = Bun.file(filePath);
return new Response(file, {
headers: {
'Cache-Control': 'public, max-age=3600', // 1 hour cache
'Content-Type': getContentType(filePath)
}
});
} catch (error) {
return new Response('File not found', { status: 404 });
}
},
});
function getContentType(filePath: string): string {
const ext = filePath.split('.').pop()?.toLowerCase();
const types = {
'html': 'text/html',
'css': 'text/css',
'js': 'application/javascript',
'json': 'application/json',
'png': 'image/png',
'jpg': 'image/jpeg',
'jpeg': 'image/jpeg',
'gif': 'image/gif',
'svg': 'image/svg+xml',
'pdf': 'application/pdf',
'txt': 'text/plain'
};
return types[ext] || 'application/octet-stream';
}
// 3. Static file server with directory listing
const server = Bun.serve({
port: 3000,
async fetch(req) {
const url = new URL(req.url);
const filePath = url.pathname === '/' ? './public' : `./public${url.pathname}`;
try {
const file = Bun.file(filePath);
const exists = await file.exists();
if (exists) {
const isDirectory = filePath.endsWith('/') || !(await file.text()).startsWith('<');
if (!isDirectory) {
return new Response(file, {
headers: { 'Content-Type': getContentType(filePath) }
});
} else {
// Generate directory listing
const path = filePath.replace('./public', '');
const files = await scanDir(filePath);
const html = generateDirectoryListing(path, files);
return new Response(html, {
headers: { 'Content-Type': 'text/html' }
});
}
} else {
return new Response('File not found', { status: 404 });
}
} catch (error) {
return new Response('Server error', { status: 500 });
}
},
});
async function scanDir(dirPath: string): Promise<string[]> {
try {
const files = [];
for await (const file of Bun.glob(`${dirPath}/*`)) {
files.push(file.replace('./public/', ''));
}
return files;
} catch (error) {
return [];
}
}
function generateDirectoryListing(path: string, files: string[]): string {
return `
<!DOCTYPE html>
<html>
<head>
<title>Directory listing for ${path}</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.file-list { list-style: none; padding: 0; }
.file-list li { margin: 5px 0; }
.file-list a { text-decoration: none; color: #007bff; }
.file-list a:hover { text-decoration: underline; }
</style>
</head>
<body>
<h1>Directory listing for ${path || '/'}</h1>
<ul class="file-list">
${path ? '<li><a href="../">../</a></li>' : ''}
${files.map(file => {
const isDirectory = file.endsWith('/');
return `<li><a href="${file}">${file}</a></li>`;
}).join('')}
</ul>
</body>
</html>
`;
}
// 4. Static file server with compression
const server = Bun.serve({
port: 3000,
async fetch(req) {
const url = new URL(req.url);
const filePath = url.pathname === '/' ? './public/index.html' : `./public${url.pathname}`;
try {
const file = Bun.file(filePath);
const exists = await file.exists();
if (!exists) {
return new Response('File not found', { status: 404 });
}
const acceptEncoding = req.headers.get('accept-encoding') || '';
const shouldGzip = acceptEncoding.includes('gzip') &&
filePath.match(/\.(js|css|html|txt|json|svg)$/);
if (shouldGzip) {
const compressed = await Bun.gzip(await file.arrayBuffer());
return new Response(compressed, {
headers: {
'Content-Type': getContentType(filePath),
'Content-Encoding': 'gzip',
'Cache-Control': 'public, max-age=3600'
}
});
}
return new Response(file, {
headers: {
'Content-Type': getContentType(filePath),
'Cache-Control': 'public, max-age=3600'
}
});
} catch (error) {
return new Response('Server error', { status: 500 });
}
},
});
console.log(`🦊 Bun static file server running at http://localhost:${server.port}`);
💻 Bun.serve REST API Server typescript
🟡 intermediate
Complete REST API server with CRUD operations and middleware
// Bun.serve REST API Server Examples
interface User {
id: number;
name: string;
email: string;
createdAt: string;
}
interface Todo {
id: number;
title: string;
completed: boolean;
userId: number;
createdAt: string;
}
// In-memory database
let users: User[] = [
{ id: 1, name: 'John Doe', email: '[email protected]', createdAt: new Date().toISOString() },
{ id: 2, name: 'Jane Smith', email: '[email protected]', createdAt: new Date().toISOString() }
];
let todos: Todo[] = [
{ id: 1, title: 'Learn Bun.serve', completed: false, userId: 1, createdAt: new Date().toISOString() },
{ id: 2, title: 'Build REST API', completed: true, userId: 1, createdAt: new Date().toISOString() }
];
let userIdCounter = 3;
let todoIdCounter = 3;
// 1. Basic REST API server
const server = Bun.serve({
port: 3000,
async fetch(req) {
const url = new URL(req.url);
const method = req.method;
const path = url.pathname;
// CORS headers
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
};
// Handle OPTIONS requests for CORS
if (method === 'OPTIONS') {
return new Response(null, { headers: corsHeaders });
}
try {
// Users API
if (path.startsWith('/api/users')) {
if (path === '/api/users') {
if (method === 'GET') {
return Response.json(users, { headers: corsHeaders });
} else if (method === 'POST') {
const body = await req.json();
const newUser: User = {
id: userIdCounter++,
name: body.name,
email: body.email,
createdAt: new Date().toISOString()
};
users.push(newUser);
return Response.json(newUser, {
status: 201,
headers: corsHeaders
});
}
} else if (path.match(/^\/api\/users\/\d+$/)) {
const userId = parseInt(path.split('/').pop()!);
const userIndex = users.findIndex(u => u.id === userId);
if (userIndex === -1) {
return Response.json({ error: 'User not found' }, {
status: 404,
headers: corsHeaders
});
}
if (method === 'GET') {
return Response.json(users[userIndex], { headers: corsHeaders });
} else if (method === 'PUT') {
const body = await req.json();
users[userIndex] = { ...users[userIndex], ...body };
return Response.json(users[userIndex], { headers: corsHeaders });
} else if (method === 'DELETE') {
const deletedUser = users.splice(userIndex, 1)[0];
return Response.json(deletedUser, { headers: corsHeaders });
}
}
}
// Todos API
if (path.startsWith('/api/todos')) {
if (path === '/api/todos') {
if (method === 'GET') {
const userId = url.searchParams.get('userId');
const userTodos = userId ?
todos.filter(t => t.userId === parseInt(userId)) :
todos;
return Response.json(userTodos, { headers: corsHeaders });
} else if (method === 'POST') {
const body = await req.json();
const newTodo: Todo = {
id: todoIdCounter++,
title: body.title,
completed: false,
userId: body.userId,
createdAt: new Date().toISOString()
};
todos.push(newTodo);
return Response.json(newTodo, {
status: 201,
headers: corsHeaders
});
}
} else if (path.match(/^\/api\/todos\/\d+$/)) {
const todoId = parseInt(path.split('/').pop()!);
const todoIndex = todos.findIndex(t => t.id === todoId);
if (todoIndex === -1) {
return Response.json({ error: 'Todo not found' }, {
status: 404,
headers: corsHeaders
});
}
if (method === 'GET') {
return Response.json(todos[todoIndex], { headers: corsHeaders });
} else if (method === 'PUT') {
const body = await req.json();
todos[todoIndex] = { ...todos[todoIndex], ...body };
return Response.json(todos[todoIndex], { headers: corsHeaders });
} else if (method === 'DELETE') {
const deletedTodo = todos.splice(todoIndex, 1)[0];
return Response.json(deletedTodo, { headers: corsHeaders });
}
}
}
// Health check
if (path === '/health') {
return Response.json({
status: 'ok',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
stats: {
users: users.length,
todos: todos.length
}
}, { headers: corsHeaders });
}
return new Response('Not Found', { status: 404, headers: corsHeaders });
} catch (error) {
return Response.json({
error: 'Internal Server Error',
message: error.message
}, { status: 500, headers: corsHeaders });
}
},
});
// 2. API server with middleware
const createApiServer = () => {
const middlewares: Array<(req: Request, next: () => Promise<Response>) => Promise<Response>> = [];
// CORS middleware
const corsMiddleware = async (req: Request, next: () => Promise<Response>) => {
const response = await next();
// Add CORS headers to all responses
Object.entries({
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
}).forEach(([key, value]) => {
response.headers.set(key, value);
});
return response;
};
// Logging middleware
const loggingMiddleware = async (req: Request, next: () => Promise<Response>) => {
const start = Date.now();
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
const response = await next();
const duration = Date.now() - start;
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url} - ${response.status} (${duration}ms)`);
return response;
};
// Rate limiting middleware
const rateLimitMap = new Map<string, { count: number; resetTime: number }>();
const rateLimitMiddleware = async (req: Request, next: () => Promise<Response>) => {
const ip = req.headers.get('x-forwarded-for') || 'unknown';
const now = Date.now();
const windowMs = 60000; // 1 minute
const maxRequests = 100;
const record = rateLimitMap.get(ip);
if (!record || now > record.resetTime) {
rateLimitMap.set(ip, { count: 1, resetTime: now + windowMs });
return await next();
}
if (record.count >= maxRequests) {
return new Response('Too Many Requests', { status: 429 });
}
record.count++;
return await next();
};
middlewares.push(corsMiddleware, loggingMiddleware, rateLimitMiddleware);
// Request handler
const handler = async (req: Request): Promise<Response> => {
const url = new URL(req.url);
const path = url.pathname;
// API routes
if (path === '/api/data') {
return Response.json({
message: 'Hello from middleware!',
timestamp: new Date().toISOString()
});
}
return new Response('Not Found', { status: 404 });
};
// Execute middleware chain
const executeMiddleware = async (req: Request, index = 0): Promise<Response> => {
if (index >= middlewares.length) {
return await handler(req);
}
return await middlewares[index](req, () => executeMiddleware(req, index + 1));
};
return executeMiddleware;
};
const serverWithMiddleware = Bun.serve({
port: 3001,
fetch: createApiServer(),
});
console.log(`🦊 Bun API server running at http://localhost:${server.port}`);
console.log(`🦊 Bun API server with middleware running at http://localhost:${serverWithMiddleware.port}`);