Web Development Basics
Creating an HTTP Server
Basic HTTP Server Implementation:
import { serve } from 'bun'
const server = serve({
port: 3000,
fetch(request) {
// Handle request and return response
return new Response('Hello Bun!', {
headers: { 'Content-Type': 'text/plain' }
})
}
})
console.log(`Server running at http://localhost:${server.port}`)Advanced Server Configuration:
serve({
port: 3000,
hostname: '0.0.0.0', // Listen on all network interfaces
development: true, // Development mode (auto-reload)
https: { // HTTPS configuration
certFile: './cert.pem',
keyFile: './key.pem'
},
fetch(request, server) {
// Access server object for additional information
const url = new URL(request.url)
return handleRequest(url.pathname, request)
}
})Routing and Request Handling
Custom Routing Implementation:
const routes = {
'/': () => new Response('Home Page'),
'/about': () => new Response('About Page'),
'/api/users': async () => {
const users = await getUsersFromDB()
return new Response(JSON.stringify(users), {
headers: { 'Content-Type': 'application/json' }
})
}
}
serve({
fetch(request) {
const url = new URL(request.url)
const handler = routes[url.pathname]
if (handler) {
return handler(request)
}
return new Response('404 Not Found', { status: 404 })
}
})Middleware Mechanism Implementation:
function createMiddleware(handler, ...middlewares) {
return async (request) => {
let chain = handler
// Wrap middleware in reverse order
for (const middleware of middlewares.reverse()) {
const next = chain
chain = () => middleware(request, next)
}
return chain()
}
}
// Usage example
const logger = (request, next) => {
console.log(`${request.method} ${request.url}`)
return next()
}
const auth = (request, next) => {
const token = request.headers.get('Authorization')
if (!token) throw new Error('Unauthorized')
return next()
}
const handler = createMiddleware(
(request) => new Response('Protected Content'),
logger,
auth
)Static File Serving
Static File Configuration:
serve({
port: 3000,
fetch(request) {
const url = new URL(request.url)
if (url.pathname.startsWith('/static/')) {
// Serve static files directly from the file system
return Bun.file(`./public${url.pathname}`).response
}
// Other requests handled by dynamic routing
return handleDynamicRequest(request)
}
})Optimized Static File Serving:
import { MIME_TYPES } from './mime-types'
serve({
fetch(request) {
const url = new URL(request.url)
const filePath = `./public${url.pathname}`
// Check if file exists
if (Bun.file(filePath).exists()) {
// Get file extension to set Content-Type
const ext = filePath.split('.').pop()
const contentType = MIME_TYPES[ext] || 'application/octet-stream'
// Set cache headers
const headers = new Headers({
'Content-Type': contentType,
'Cache-Control': 'public, max-age=3600'
})
return Bun.file(filePath).response
.then(response => new Response(response.body, {
headers,
status: response.status
}))
}
return new Response('Not Found', { status: 404 })
}
})Template Engine Integration
EJS Template Integration:
import { serve } from 'bun'
import ejs from 'ejs'
serve({
fetch(request) {
if (request.url === '/home') {
const data = { title: 'Home Page', user: { name: 'Bun User' } }
const html = ejs.renderFile('./views/home.ejs', data)
return new Response(html, {
headers: { 'Content-Type': 'text/html' }
})
}
return new Response('Not Found', { status: 404 })
}
})Pug Template Integration:
import { serve } from 'bun'
import pug from 'pug'
serve({
fetch(request) {
if (request.url === '/about') {
const data = { title: 'About Us', features: ['Fast', 'Lightweight'] }
const html = pug.renderFile('./views/about.pug', data)
return new Response(html, {
headers: { 'Content-Type': 'text/html' }
})
}
return new Response('Not Found', { status: 404 })
}
})RESTful API Design and Implementation
RESTful API Example:
import { serve } from 'bun'
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]
serve({
fetch(request) {
const url = new URL(request.url)
const id = parseInt(url.searchParams.get('id'))
switch (url.pathname) {
case '/api/users':
if (request.method === 'GET') {
return new Response(JSON.stringify(users), {
headers: { 'Content-Type': 'application/json' }
})
} else if (request.method === 'POST') {
const user = await request.json()
users.push(user)
return new Response(JSON.stringify(user), {
status: 201,
headers: { 'Content-Type': 'application/json' }
})
}
break
case `/api/users/${id}`:
if (request.method === 'GET') {
const user = users.find(u => u.id === id)
if (user) {
return new Response(JSON.stringify(user), {
headers: { 'Content-Type': 'application/json' }
})
}
return new Response('User not found', { status: 404 })
} else if (request.method === 'DELETE') {
users = users.filter(u => u.id !== id)
return new Response(null, { status: 204 })
}
break
}
return new Response('Not Found', { status: 404 })
}
})API Best Practices:
- Use appropriate HTTP status codes
- Standardize response formats
- Implement request validation
- Add version control (/api/v1/users)
- Use middleware for CORS and authentication
Database Interaction
MySQL Database Connection
mysql2 Basic Operations:
import mysql from 'mysql2/promise'
async function main() {
// Create connection pool
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password',
database: 'test_db',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
})
// Execute query
const [rows] = await pool.execute('SELECT * FROM users WHERE id = ?', [1])
console.log(rows)
// Insert data
const [result] = await pool.execute(
'INSERT INTO users (name, email) VALUES (?, ?)',
['Bun User', 'user@example.com']
)
console.log('Inserted ID:', result.insertId)
await pool.end()
}
main()PostgreSQL Database Operations
pg Module Usage:
import { Client } from 'pg'
async function main() {
const client = new Client({
user: 'postgres',
host: 'localhost',
database: 'test_db',
password: 'password',
port: 5432,
})
await client.connect()
// Execute query
const res = await client.query('SELECT * FROM users WHERE id = $1', [1])
console.log(res.rows)
// Transaction handling
await client.query('BEGIN')
try {
await client.query('UPDATE accounts SET balance = balance - $1 WHERE id = $2', [100, 1])
await client.query('UPDATE accounts SET balance = balance + $1 WHERE id = $2', [100, 2])
await client.query('COMMIT')
} catch (err) {
await client.query('ROLLBACK')
throw err
}
await client.end()
}
main()SQLite Database Operations
better-sqlite3 Usage:
import Database from 'better-sqlite3'
const db = new Database('test.db')
// Create table
db.exec(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL
)
`)
// Insert data
const stmt = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)')
const info = stmt.run('Bun User', 'user@example.com')
console.log('Inserted ID:', info.lastInsertRowid)
// Query data
const rows = db.prepare('SELECT * FROM users').all()
console.log(rows)
db.close()Database Connection Pool Optimization
Connection Pool Best Practices:
// Optimized MySQL connection pool configuration
const pool = mysql.createPool({
connectionLimit: 10, // Maximum connections
queueLimit: 0, // Unlimited queuing
acquireTimeout: 10000, // Connection acquisition timeout (ms)
idleTimeout: 60000, // Idle connection timeout
enableKeepAlive: true, // Keep connections alive
keepAliveInitialDelay: 0 // Initial delay
})
// PostgreSQL connection pool
import { Pool } from 'pg'
const pool = new Pool({
max: 20, // Maximum clients
idleTimeoutMillis: 30000, // Idle connection timeout
connectionTimeoutMillis: 2000 // Connection timeout
})Performance Optimization Techniques:
- Use prepared statements
- Batch operations instead of single operations
- Set appropriate connection pool size
- Implement connection health checks
- Use caching to reduce database queries
ORM and ODM Selection
Prisma Example:
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() {
// Create record
const user = await prisma.user.create({
data: {
name: 'Bun User',
email: 'user@example.com'
}
})
// Query records
const users = await prisma.user.findMany({
where: {
email: { contains: 'example' }
}
})
// Complex query
const result = await prisma.$queryRaw`
SELECT * FROM users
WHERE id IN (SELECT user_id FROM posts WHERE views > 100)
`
}
main()TypeORM Example:
import "reflect-metadata"
import { createConnection } from "typeorm"
import { User } from "./entity/User"
createConnection().then(async connection => {
const user = new User()
user.firstName = "Bun"
user.lastName = "User"
await connection.manager.save(user)
const users = await connection.manager.find(User)
console.log(users)
}).catch(error => console.log(error))Selection Recommendations:
| Requirement | Recommended Tool |
|---|---|
| Rapid Development | Prisma |
| Complex Queries | TypeORM |
| MongoDB | Mongoose (ODM) |
| High Performance | Direct SQL libraries |
Command-Line Tool Development
Command-Line Argument Parsing
minimist Usage Example:
import minimist from 'minimist'
const argv = minimist(process.argv.slice(2))
console.log(argv)
// Usage example:
// node cli.js --name=Bun --verbose --count=3
// Output: { _: [], name: 'Bun', verbose: true, count: 3 }yargs Advanced Usage:
import yargs from 'yargs/yargs'
import { hideBin } from 'yargs/helpers'
yargs(hideBin(process.argv))
.option('name', {
alias: 'n',
type: 'string',
description: 'Your name'
})
.option('verbose', {
alias: 'v',
type: 'boolean',
description: 'Verbose output'
})
.command('greet', 'Greet the user', () => {}, (argv) => {
console.log(`Hello, ${argv.name}!`)
})
.help()
.argvFile System Operations
File Operation Example:
import {
readFileSync,
writeFileSync,
readdirSync,
statSync
} from 'fs'
import path from 'path'
// Read file
const content = readFileSync('config.json', 'utf-8')
console.log(content)
// Write file
writeFileSync('output.txt', 'Hello Bun!')
// Traverse directory
const files = readdirSync('./src')
files.forEach(file => {
const filePath = path.join('./src', file)
const stats = statSync(filePath)
if (stats.isDirectory()) {
console.log('Directory:', file)
} else {
console.log('File:', file)
}
})Colored Output and Progress Bars
chalk Usage Example:
import chalk from 'chalk'
console.log(chalk.blue('Hello world!'))
console.log(chalk.red.bold('Error message'))
console.log(chalk.green('Success message'))
console.log(chalk.yellow.inverse('Warning'))
// Combine styles
console.log(chalk.blue.bgRed.bold('Red on blue'))ora Progress Bar Example:
import ora from 'ora'
const spinner = ora('Loading unicorns').start()
setTimeout(() => {
spinner.color = 'yellow'
spinner.text = 'Loading rainbows'
}, 1000)
setTimeout(() => {
spinner.succeed('Done!')
}, 2000)Scaffolding Tool Development
Basic Scaffolding Implementation:
#!/usr/bin/env bun
import { copySync, ensureDirSync, existsSync } from 'fs-extra'
import path from 'path'
import chalk from 'chalk'
// Project template directory
const templateDir = path.join(__dirname, 'templates', 'basic')
// Create project
async function createProject(projectName) {
const projectPath = path.join(process.cwd(), projectName)
if (existsSync(projectPath)) {
console.error(chalk.red(`Error: ${projectName} already exists`))
process.exit(1)
}
console.log(chalk.blue(`Creating project ${projectName}...`))
// Copy template files
ensureDirSync(projectPath)
copySync(templateDir, projectPath)
// Replace placeholders
const packageJsonPath = path.join(projectPath, 'package.json')
let packageJson = readFileSync(packageJsonPath, 'utf-8')
packageJson = packageJson.replace(/{{projectName}}/g, projectName)
writeFileSync(packageJsonPath, packageJson)
console.log(chalk.green(`Success: ${projectName} created successfully`))
}
// Parse command-line arguments
const argv = process.argv.slice(2)
if (argv.length === 0) {
console.log(chalk.yellow('Usage: bun run cli.js <project-name>'))
process.exit(1)
}
createProject(argv[0])Global vs Local Installation
Installation Methods Comparison:
| Feature | Global Installation | Local Installation |
|---|---|---|
| Installation Location | System-wide directory | Project node_modules |
| Usage | Direct command-line invocation | Via npx or package.json scripts |
| Use Case | Command-line tools | Project dependency tools |
| Version Management | Single version | Different versions per project |
package.json Script Configuration:
{
"scripts": {
"lint": "eslint src",
"format": "prettier --write src",
"build": "bun build src/index.ts --outfile dist/bundle.js"
}
}Global Tool Development Recommendations:
- Provide clear error messages
- Support –help parameter for help information
- Implement version checking (–version)
- Use colored output for improved readability
- Add progress indicators (ora)



