Deploying Bun Applications
This comprehensive guide covers everything you need to know about deploying Bun applications with Flux-Orbit, from simple Elysia APIs to complex applications using Hono, or even Node.js-compatible frameworks running on Bun.
Overview
Flux-Orbit automatically detects Bun applications by looking for:
bun.lockbfile (Bun's binary lockfile)bunfig.toml(Bun configuration file).bun-versionfor version specification (optional)
Basic Bun Deployment
Simple Elysia API
docker run -d \
--name elysia-api \
-e GIT_REPO_URL=https://github.com/your-username/elysia-api \
-e APP_PORT=3000 \
-p 3000:3000 \
runonflux/orbit:latest
What Happens Automatically
- Detection: Finds
bun.lockborbunfig.tomland identifies as Bun project - Version Selection:
- Checks
BUN_VERSIONenvironment variable - Checks
.bun-versionfile - Checks
engines.bunin package.json - Falls back to latest Bun version
- Checks
- Runtime Installation:
- Downloads official Bun binary from bun.sh
- Installs to
/opt/flux-tools/bun - Sets up PATH environment variables
- Dependencies: Runs
bun install - Build: Runs
bun run buildif build script exists (optional - Bun runs TypeScript natively!) - Start: Executes
bun run startor detected entry point
Framework-Specific Guides
Elysia Framework
Elysia is a Bun-native web framework designed for ergonomics and performance. Flux-Orbit automatically detects and optimizes Elysia applications:
docker run -d \
--name elysia-rest-api \
-e GIT_REPO_URL=https://github.com/your-username/elysia-api \
-e APP_PORT=3000 \
-e BUN_VERSION=1.0.25 \
-p 3000:3000 \
runonflux/orbit:latest
Example index.ts:
import { Elysia } from 'elysia';
const app = new Elysia();
const port = process.env.APP_PORT || 3000;
app.get('/health', () => ({
status: 'healthy',
runtime: 'bun',
framework: 'elysia'
}));
app.get('/', () => ({
message: 'Hello from Elysia!',
runtime: `Bun ${Bun.version}`
}));
app.listen(port, () => {
console.log(`🦊 Elysia is running on port ${port}`);
});
Key Features:
- Native TypeScript support (no transpilation needed)
- Type safety with end-to-end type inference
- High performance with Bun's optimizations
Hono Framework
Hono is an ultra-fast web framework that works great with Bun:
docker run -d \
--name hono-api \
-e GIT_REPO_URL=https://github.com/your-username/hono-api \
-e APP_PORT=3000 \
-p 3000:3000 \
runonflux/orbit:latest
Example index.ts:
import { Hono } from 'hono';
const app = new Hono();
const port = Number(process.env.APP_PORT) || 3000;
app.get('/health', (c) => {
return c.json({ status: 'healthy', runtime: 'bun' });
});
app.get('/', (c) => {
return c.json({
message: 'Hello from Hono!',
runtime: `Bun ${Bun.version}`
});
});
export default {
port,
fetch: app.fetch,
};
console.log(`🔥 Hono is running on port ${port}`);
Express on Bun
Bun is compatible with Node.js frameworks like Express:
docker run -d \
--name express-bun \
-e GIT_REPO_URL=https://github.com/your-username/express-app \
-e APP_PORT=3000 \
-p 3000:3000 \
runonflux/orbit:latest
Example:
import express from 'express';
const app = express();
const port = process.env.APP_PORT || 3000;
app.get('/health', (req, res) => {
res.json({ status: 'healthy', runtime: 'bun' });
});
app.get('/', (req, res) => {
res.json({ message: 'Express running on Bun!' });
});
app.listen(port, () => {
console.log(`Express on Bun listening on port ${port}`);
});
Next.js on Bun
Bun can run Next.js applications:
docker run -d \
--name nextjs-bun \
-e GIT_REPO_URL=https://github.com/your-username/nextjs-app \
-e APP_PORT=3000 \
-p 3000:3000 \
runonflux/orbit:latest
Note: Ensure your package.json has a start script:
{
"scripts": {
"build": "next build",
"start": "next start"
}
}
Version Management
Specify Bun Version
Option 1: Environment Variable
docker run -d \
-e GIT_REPO_URL=https://github.com/your-username/bun-app \
-e APP_PORT=3000 \
-e BUN_VERSION=1.0.25 \
-p 3000:3000 \
runonflux/orbit:latest
Option 2: .bun-version File
1.0.25
Option 3: package.json Engines
{
"name": "my-bun-app",
"engines": {
"bun": ">=1.0.0"
}
}
Native TypeScript Execution
One of Bun's killer features is native TypeScript execution - no build step required!
TypeScript Without Build
docker run -d \
--name ts-api \
-e GIT_REPO_URL=https://github.com/your-username/typescript-api \
-e APP_PORT=3000 \
-p 3000:3000 \
runonflux/orbit:latest
Your index.ts runs directly without transpilation:
interface ApiResponse {
message: string;
timestamp: Date;
}
const response: ApiResponse = {
message: 'TypeScript running natively!',
timestamp: new Date()
};
console.log(response);
When to Use Build Scripts
Use a build script when you need:
- Asset bundling for frontend applications
- Code minification for production
- Special build optimizations
{
"scripts": {
"build": "bun build ./src/index.ts --outdir ./dist --target bun",
"start": "bun run ./dist/index.js"
}
}
Environment Variables
Bun-Specific Variables
| Variable | Description | Default |
|---|---|---|
BUN_VERSION | Bun version to install | Auto-detected or latest |
Common Application Variables
docker run -d \
--name bun-api \
-e GIT_REPO_URL=https://github.com/your-username/bun-api \
-e APP_PORT=3000 \
-e BUN_VERSION=1.0.25 \
-e DATABASE_URL=postgres://user:pass@db:5432/mydb \
-e JWT_SECRET=your-secret-key \
-e LOG_LEVEL=info \
-p 3000:3000 \
runonflux/orbit:latest
Advanced Scenarios
Monorepo - Deploy Specific Package
docker run -d \
--name bun-auth-service \
-e GIT_REPO_URL=https://github.com/your-username/monorepo \
-e PROJECT_PATH=packages/auth \
-e APP_PORT=3000 \
-p 3000:3000 \
runonflux/orbit:latest
Private Repository
docker run -d \
--name private-bun-api \
-e GIT_REPO_URL=https://github.com/your-username/private-api \
-e GIT_TOKEN=ghp_your_personal_access_token \
-e APP_PORT=3000 \
-p 3000:3000 \
runonflux/orbit:latest
With Deployment Hooks
Create pre-deploy.sh in your repository root:
#!/bin/bash
# Check Bun runtime before deployment
echo "Checking Bun runtime..."
bun --version
# Run tests
echo "Running tests..."
bun test
Create post-deploy.sh:
#!/bin/bash
# Health check after deployment
echo "Performing health check..."
curl -f http://localhost:$APP_PORT/health || exit 1
echo "Deployment successful!"
docker run -d \
--name bun-api-with-hooks \
-e GIT_REPO_URL=https://github.com/your-username/bun-api \
-e APP_PORT=3000 \
-p 3000:3000 \
runonflux/orbit:latest
CI/CD Integration
Automatic Deployment with Webhooks
docker run -d \
--name bun-api \
-e GIT_REPO_URL=https://github.com/your-username/bun-api \
-e APP_PORT=3000 \
-e WEBHOOK_SECRET=my-secret-phrase \
-p 3000:3000 \
-p 9001:9001 \
runonflux/orbit:latest
Configure GitHub Webhook:
- Payload URL:
https://your-app-9001.app.runonflux.io/webhook - Content type:
application/json - Secret:
my-secret-phrase - Events: Just the
pushevent
Polling for Updates
docker run -d \
--name bun-api \
-e GIT_REPO_URL=https://github.com/your-username/bun-api \
-e APP_PORT=3000 \
-e POLLING_INTERVAL=300 \
-p 3000:3000 \
runonflux/orbit:latest
Troubleshooting
Bun Not Detected
Problem: Application detected as Node.js instead of Bun
Solution: Ensure you have bun.lockb in your repository:
# Generate bun.lockb
bun install
git add bun.lockb
git commit -m "Add bun.lockb for Bun detection"
Entry Point Not Found
Problem: "No entry point found for Bun application"
Solution: Ensure you have either:
- A
startscript in package.json:
{
"scripts": {
"start": "bun run index.ts"
}
}
- Or a common entry point file:
index.ts,index.js,src/index.ts,main.ts,server.ts, orapp.ts
Port Binding Issues
Problem: Application not accessible
Solution: Ensure your Bun application binds to 0.0.0.0 (not localhost):
// Good: Accessible from outside container
app.listen(port, '0.0.0.0', () => {
console.log(`Server running on port ${port}`);
});
// Also good (default in most frameworks)
app.listen(port);
TypeScript Type Errors
Problem: TypeScript compilation errors even though Bun runs TS natively
Solution: Bun runs TypeScript without strict type checking. For development, fix type errors locally:
# Check types locally before pushing
bun run tsc --noEmit
Add to package.json:
{
"scripts": {
"typecheck": "tsc --noEmit",
"start": "bun run index.ts"
}
}
Dependencies Not Installing
Problem: bun install fails
Solution: Check for bunfig.toml configuration issues or try clearing Bun cache:
# In pre-deploy.sh
bun pm cache rm
bun install
Performance Tips
- Native TypeScript: Skip build steps when possible - Bun runs TypeScript natively
- Bun.serve API: For maximum performance, use Bun's native server API instead of Express
- Dependency Caching: Dependencies are cached based on bun.lockb hash
- Health Checks: Implement
/healthendpoint for faster deployment verification - Hot Module Reloading: Use
bun --hotin development (not needed in production)
Bun-Native APIs
Bun provides high-performance native APIs:
Bun.serve (High Performance)
const server = Bun.serve({
port: process.env.APP_PORT || 3000,
fetch(req) {
const url = new URL(req.url);
if (url.pathname === '/health') {
return new Response(JSON.stringify({ status: 'healthy' }), {
headers: { 'Content-Type': 'application/json' }
});
}
return new Response('Hello from Bun.serve!');
},
});
console.log(`Server running on port ${server.port}`);
File I/O with Bun.file
// Fast file reading
const file = Bun.file('data.json');
const data = await file.json();
// Fast file writing
await Bun.write('output.json', JSON.stringify(data));
SQLite with Bun
import { Database } from 'bun:sqlite';
const db = new Database('mydb.sqlite');
const query = db.query('SELECT * FROM users WHERE id = ?');
const user = query.get(1);
Example Repository Structure
my-bun-api/
├── package.json # Dependencies and scripts
├── bun.lockb # Bun lockfile (binary format)
├── .bun-version # Optional: Pin Bun version
├── bunfig.toml # Optional: Bun configuration
├── tsconfig.json # TypeScript configuration
├── index.ts # Application entry point
├── pre-deploy.sh # Optional: Pre-deployment hook
├── post-deploy.sh # Optional: Post-deployment hook
├── src/
│ ├── routes/
│ │ ├── users.ts
│ │ └── auth.ts
│ ├── models/
│ │ └── user.ts
│ └── middleware/
│ └── auth.ts
└── test/
└── api.test.ts