High-performance applications with Bun runtime including native APIs, bundling, and testing
# Bun Runtime Development for Google Antigravity
Build blazing-fast applications with Bun runtime using Google Antigravity's Gemini 3 engine. This guide covers Bun APIs, HTTP server, bundling, and testing patterns.
## Bun HTTP Server
```typescript
// src/server.ts
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { logger } from 'hono/logger';
import { jwt } from 'hono/jwt';
const app = new Hono();
// Middleware
app.use('*', logger());
app.use('/api/*', cors());
// JWT authentication for protected routes
app.use('/api/protected/*', jwt({
secret: process.env.JWT_SECRET!,
}));
// Health check
app.get('/health', (c) => {
return c.json({
status: 'healthy',
runtime: 'bun',
version: Bun.version,
});
});
// File upload with Bun.file
app.post('/api/upload', async (c) => {
const formData = await c.req.formData();
const file = formData.get('file') as File;
if (!file) {
return c.json({ error: 'No file provided' }, 400);
}
const buffer = await file.arrayBuffer();
const filename = `uploads/${Date.now()}-${file.name}`;
await Bun.write(filename, buffer);
return c.json({
filename,
size: file.size,
type: file.type,
});
});
// Serve static files
app.get('/static/*', async (c) => {
const path = c.req.path.replace('/static', './public');
const file = Bun.file(path);
if (!(await file.exists())) {
return c.notFound();
}
return new Response(file, {
headers: {
'Content-Type': file.type,
'Cache-Control': 'public, max-age=31536000',
},
});
});
// WebSocket support
app.get('/ws', (c) => {
const upgradeHeader = c.req.header('Upgrade');
if (upgradeHeader !== 'websocket') {
return c.text('Expected WebSocket', 426);
}
// Handle upgrade in Bun.serve
return c.text('WebSocket upgrade handled by Bun.serve');
});
export default app;
// Start server
const server = Bun.serve({
port: process.env.PORT || 3000,
fetch: app.fetch,
websocket: {
open(ws) {
console.log('WebSocket connected');
ws.subscribe('broadcast');
},
message(ws, message) {
console.log('Received:', message);
ws.publish('broadcast', message);
},
close(ws) {
console.log('WebSocket disconnected');
ws.unsubscribe('broadcast');
},
},
});
console.log(`Server running at http://localhost:${server.port}`);
```
## Bun SQLite Database
```typescript
// src/database.ts
import { Database } from 'bun:sqlite';
const db = new Database('app.db', { create: true });
// Create tables
db.run(`
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
password_hash TEXT NOT NULL,
created_at TEXT DEFAULT CURRENT_TIMESTAMP
)
`);
db.run(`
CREATE TABLE IF NOT EXISTS posts (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
title TEXT NOT NULL,
content TEXT,
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
)
`);
// Prepared statements for better performance
const statements = {
getUserById: db.prepare('SELECT * FROM users WHERE id = ?'),
getUserByEmail: db.prepare('SELECT * FROM users WHERE email = ?'),
createUser: db.prepare('INSERT INTO users (id, email, name, password_hash) VALUES (?, ?, ?, ?)'),
updateUser: db.prepare('UPDATE users SET name = ?, email = ? WHERE id = ?'),
deleteUser: db.prepare('DELETE FROM users WHERE id = ?'),
getPostsByUser: db.prepare('SELECT * FROM posts WHERE user_id = ? ORDER BY created_at DESC'),
createPost: db.prepare('INSERT INTO posts (id, user_id, title, content) VALUES (?, ?, ?, ?)'),
};
interface User {
id: string;
email: string;
name: string;
password_hash: string;
created_at: string;
}
interface Post {
id: string;
user_id: string;
title: string;
content: string;
created_at: string;
}
export const userRepository = {
findById(id: string): User | null {
return statements.getUserById.get(id) as User | null;
},
findByEmail(email: string): User | null {
return statements.getUserByEmail.get(email) as User | null;
},
create(user: Omit<User, 'created_at'>): User {
statements.createUser.run(user.id, user.email, user.name, user.password_hash);
return this.findById(user.id)!;
},
update(id: string, data: { name?: string; email?: string }): User | null {
const user = this.findById(id);
if (!user) return null;
statements.updateUser.run(
data.name ?? user.name,
data.email ?? user.email,
id
);
return this.findById(id);
},
delete(id: string): boolean {
const result = statements.deleteUser.run(id);
return result.changes > 0;
},
};
export const postRepository = {
findByUser(userId: string): Post[] {
return statements.getPostsByUser.all(userId) as Post[];
},
create(post: Omit<Post, 'created_at'>): Post {
statements.createPost.run(post.id, post.user_id, post.title, post.content);
return db.prepare('SELECT * FROM posts WHERE id = ?').get(post.id) as Post;
},
};
// Transaction helper
export function transaction<T>(fn: () => T): T {
return db.transaction(fn)();
}
export { db };
```
## Bun Testing
```typescript
// src/user.test.ts
import { describe, test, expect, beforeAll, afterAll, beforeEach } from 'bun:test';
import { userRepository, db } from './database';
describe('User Repository', () => {
beforeAll(() => {
// Setup test database
db.run('DELETE FROM users');
});
beforeEach(() => {
db.run('DELETE FROM users');
});
test('should create a user', () => {
const user = userRepository.create({
id: 'test-1',
email: 'test@example.com',
name: 'Test User',
password_hash: 'hashed',
});
expect(user.id).toBe('test-1');
expect(user.email).toBe('test@example.com');
expect(user.name).toBe('Test User');
});
test('should find user by id', () => {
userRepository.create({
id: 'test-2',
email: 'test2@example.com',
name: 'Test User 2',
password_hash: 'hashed',
});
const user = userRepository.findById('test-2');
expect(user).not.toBeNull();
expect(user!.email).toBe('test2@example.com');
});
test('should return null for non-existent user', () => {
const user = userRepository.findById('non-existent');
expect(user).toBeNull();
});
test('should update user', () => {
userRepository.create({
id: 'test-3',
email: 'test3@example.com',
name: 'Original Name',
password_hash: 'hashed',
});
const updated = userRepository.update('test-3', { name: 'Updated Name' });
expect(updated!.name).toBe('Updated Name');
expect(updated!.email).toBe('test3@example.com');
});
test('should delete user', () => {
userRepository.create({
id: 'test-4',
email: 'test4@example.com',
name: 'To Delete',
password_hash: 'hashed',
});
const deleted = userRepository.delete('test-4');
expect(deleted).toBe(true);
const user = userRepository.findById('test-4');
expect(user).toBeNull();
});
});
// HTTP tests
describe('API Routes', () => {
test('GET /health returns healthy', async () => {
const response = await fetch('http://localhost:3000/health');
const data = await response.json();
expect(response.status).toBe(200);
expect(data.status).toBe('healthy');
expect(data.runtime).toBe('bun');
});
});
```
## Bun Bundler
```typescript
// build.ts
await Bun.build({
entrypoints: ['./src/index.ts'],
outdir: './dist',
target: 'bun',
minify: true,
splitting: true,
sourcemap: 'external',
external: ['bun:sqlite'],
define: {
'process.env.NODE_ENV': '"production"',
},
});
console.log('Build complete!');
```
## Best Practices
Google Antigravity's Gemini 3 engine recommends these Bun patterns: Use native Bun APIs for maximum performance. Leverage bun:sqlite for embedded databases. Use prepared statements for repeated queries. Implement proper error handling. Take advantage of Bun's built-in testing.This Bun prompt is ideal for developers working on:
By using this prompt, you can save hours of manual coding and ensure best practices are followed from the start. It's particularly valuable for teams looking to maintain consistency across their bun implementations.
Yes! All prompts on Antigravity AI Directory are free to use for both personal and commercial projects. No attribution required, though it's always appreciated.
This prompt works excellently with Claude, ChatGPT, Cursor, GitHub Copilot, and other modern AI coding assistants. For best results, use models with large context windows.
You can modify the prompt by adding specific requirements, constraints, or preferences. For Bun projects, consider mentioning your framework version, coding style, and any specific libraries you're using.