
Research
/Security News
npm Author Qix Compromised via Phishing Email in Major Supply Chain Attack
npm author Qixβs account was compromised, with malicious versions of popular packages like chalk-template, color-convert, and strip-ansi published.
A high-performance HTTP gateway for Bun, designed for microservices and API gateways.
The Lightning-Fast HTTP Gateway & Load Balancer for the Modern Web
Bungate is a next-generation HTTP gateway and load balancer that harnesses the incredible speed of Bun to deliver unparalleled performance for modern web applications. Built from the ground up with TypeScript, it provides enterprise-grade features with zero-config simplicity.
round-robin
, least-connections
, random
, weighted
, ip-hash
, p2c
(power-of-two-choices), latency
, weighted-least-connections
See benchmarks comparing Bungate with Nginx and Envoy in the benchmark directory.
Get up and running in less than 60 seconds:
# Install Bungate
bun add bungate
# Create your gateway
touch gateway.ts
import { BunGateway } from 'bungate'
// Create a production-ready gateway with zero config
const gateway = new BunGateway({
server: { port: 3000 },
metrics: { enabled: true }, // Enable Prometheus metrics
})
// Add intelligent load balancing
gateway.addRoute({
pattern: '/api/*',
loadBalancer: {
strategy: 'least-connections',
targets: [
{ url: 'http://api1.example.com' },
{ url: 'http://api2.example.com' },
{ url: 'http://api3.example.com' },
],
healthCheck: {
enabled: true,
interval: 30000,
timeout: 5000,
path: '/health',
},
},
})
// Add rate limiting and single target for public routes
gateway.addRoute({
pattern: '/public/*',
target: 'http://backend.example.com',
rateLimit: {
max: 1000,
windowMs: 60000,
keyGenerator: (req) => req.headers.get('x-forwarded-for') || 'unknown',
},
})
// Start the gateway
await gateway.listen()
console.log('π Bungate running on http://localhost:3000')
That's it! Your high-performance gateway is now handling traffic with:
Perfect for microservices architectures with intelligent routing:
import { BunGateway } from 'bungate'
const gateway = new BunGateway({
server: { port: 8080 },
cors: {
origin: ['https://myapp.com', 'https://admin.myapp.com'],
credentials: true,
},
})
// User service with JWT authentication
gateway.addRoute({
pattern: '/users/*',
target: 'http://user-service:3001',
auth: {
secret: process.env.JWT_SECRET || 'your-secret-key',
jwtOptions: {
algorithms: ['HS256'],
issuer: 'https://auth.myapp.com',
audience: 'https://api.myapp.com',
},
optional: false,
excludePaths: ['/users/register', '/users/login'],
},
rateLimit: {
max: 100,
windowMs: 60000,
keyGenerator: (req) =>
(req as any).user?.id || req.headers.get('x-forwarded-for') || 'unknown',
},
})
// Payment service with circuit breaker
gateway.addRoute({
pattern: '/payments/*',
target: 'http://payment-service:3002',
circuitBreaker: {
enabled: true,
failureThreshold: 3,
timeout: 5000,
resetTimeout: 5000,
},
hooks: {
onError(req, error): Promise<Response> {
// Fallback to cached payment status
return getCachedPaymentStatus(req.url)
},
},
})
Scale horizontally with multi-process clustering:
import { BunGateway } from 'bungate'
const gateway = new BunGateway({
server: { port: 3000 },
cluster: {
enabled: true,
workers: 4, // Number of worker processes
restartWorkers: true,
maxRestarts: 10,
shutdownTimeout: 30000,
},
})
// High-traffic API endpoints
gateway.addRoute({
pattern: '/api/v1/*',
loadBalancer: {
targets: [
{ url: 'http://api-server-1:8080', weight: 2 },
{ url: 'http://api-server-2:8080', weight: 2 },
{ url: 'http://api-server-3:8080', weight: 1 },
],
strategy: 'least-connections',
healthCheck: {
enabled: true,
interval: 5000,
timeout: 2000,
path: '/health',
},
},
})
// Start cluster
await gateway.listen(3000)
console.log('Cluster started with 4 workers')
Bungateβs cluster manager powers zero-downtime restarts, dynamic scaling, and safe shutdowns in production. You can control it via signals or programmatically.
SIGUSR2
to the master process
SIGTERM
or SIGINT
SIGTERM
and are given up to shutdownTimeout
to exit before being force-killedProgrammatic controls (available when using the ClusterManager
directly):
import { ClusterManager, BunGateLogger } from 'bungate'
const logger = new BunGateLogger({ level: 'info' })
const cluster = new ClusterManager(
{
enabled: true,
workers: 4,
restartWorkers: true,
restartDelay: 1000, // base delay used for exponential backoff with jitter
maxRestarts: 10, // lifetime cap per worker
respawnThreshold: 5, // sliding window cap
respawnThresholdTime: 60_000, // within this time window
shutdownTimeout: 30_000,
// Set to false when embedding in tests to avoid process.exit(0)
exitOnShutdown: true,
},
logger,
'./gateway.ts', // worker entry (executed with Bun)
)
await cluster.start()
// Dynamic scaling
await cluster.scaleUp(2) // add 2 workers
await cluster.scaleDown(1) // remove 1 worker
await cluster.scaleTo(6) // set exact worker count
// Operational visibility
console.log(cluster.getWorkerCount())
console.log(cluster.getWorkerInfo()) // includes id, restarts, pid, etc.
// Broadcast a POSIX signal to all workers (e.g., for log-level reloads)
cluster.broadcastSignal('SIGHUP')
// Target a single worker
cluster.sendSignalToWorker(1, 'SIGHUP')
// Graceful shutdown (will exit process if exitOnShutdown !== false)
// await (cluster as any).gracefulShutdown() // internal in gateway use; prefer SIGTERM
Notes:
CLUSTER_WORKER=true
and CLUSTER_WORKER_ID=<n>
environment variables.shutdownTimeout
30s, respawnThreshold
5 within 60s, restartDelay
1s, maxRestarts
10.Configuration reference (cluster):
enabled
(boolean): enable multi-process modeworkers
(number): worker process count (defaults to CPU cores)restartWorkers
(boolean): auto-respawn crashed workersrestartDelay
(ms): base delay for backoffmaxRestarts
(number): lifetime restarts per workerrespawnThreshold
(number): max restarts within time windowrespawnThresholdTime
(ms): sliding window sizeshutdownTimeout
(ms): grace period before force-killexitOnShutdown
(boolean): if true (default), master exits after shutdown; set false in tests/embeddedDistribute traffic intelligently across multiple backends:
// E-commerce platform with weighted distribution
gateway.addRoute({
pattern: '/products/*',
loadBalancer: {
strategy: 'weighted',
targets: [
{ url: 'http://products-primary:3000', weight: 70 },
{ url: 'http://products-secondary:3001', weight: 20 },
{ url: 'http://products-cache:3002', weight: 10 },
],
healthCheck: {
enabled: true,
path: '/health',
interval: 15000,
timeout: 5000,
expectedStatus: 200,
},
},
})
// Session-sticky load balancing for stateful apps
gateway.addRoute({
pattern: '/app/*',
loadBalancer: {
strategy: 'ip-hash',
targets: [
{ url: 'http://app-server-1:3000' },
{ url: 'http://app-server-2:3000' },
{ url: 'http://app-server-3:3000' },
],
stickySession: {
enabled: true,
cookieName: 'app-session',
ttl: 3600000, // 1 hour
},
},
})
Production-grade security with multiple layers:
// API Gateway with comprehensive security
gateway.addRoute({
pattern: '/api/v1/*',
target: 'http://api-backend:3000',
auth: {
// JWT authentication
secret: process.env.JWT_SECRET,
jwtOptions: {
algorithms: ['HS256', 'RS256'],
issuer: 'https://auth.myapp.com',
audience: 'https://api.myapp.com',
},
// API key authentication (fallback)
apiKeys: async (key, req) => {
const validKeys = await getValidApiKeys()
return validKeys.includes(key)
},
apiKeyHeader: 'x-api-key',
optional: false,
excludePaths: ['/api/v1/health', '/api/v1/public/*'],
},
middlewares: [
// Request validation
async (req, next) => {
if (req.method === 'POST' || req.method === 'PUT') {
const body = await req.json()
const validation = validateRequestBody(body)
if (!validation.valid) {
return new Response(JSON.stringify(validation.errors), {
status: 400,
headers: { 'Content-Type': 'application/json' },
})
}
}
return next()
},
],
rateLimit: {
max: 1000,
windowMs: 60000,
keyGenerator: (req) =>
(req as any).user?.id ||
req.headers.get('x-api-key') ||
req.headers.get('x-forwarded-for') ||
'unknown',
message: 'API rate limit exceeded',
},
proxy: {
headers: {
'X-Gateway-Version': '1.0.0',
'X-Request-ID': () => crypto.randomUUID(),
},
},
})
Bungate provides comprehensive authentication support out of the box:
// Gateway-level JWT authentication (applies to all routes)
const gateway = new BunGateway({
server: { port: 3000 },
auth: {
secret: process.env.JWT_SECRET,
jwtOptions: {
algorithms: ['HS256', 'RS256'],
issuer: 'https://auth.myapp.com',
audience: 'https://api.myapp.com',
},
excludePaths: ['/health', '/metrics', '/auth/login', '/auth/register'],
},
})
// Route-level JWT authentication (overrides gateway settings)
gateway.addRoute({
pattern: '/admin/*',
target: 'http://admin-service:3000',
auth: {
secret: process.env.ADMIN_JWT_SECRET,
jwtOptions: {
algorithms: ['RS256'],
issuer: 'https://auth.myapp.com',
audience: 'https://admin.myapp.com',
},
optional: false,
},
})
gateway.addRoute({
pattern: '/secure/*',
target: 'http://secure-service:3000',
auth: {
jwksUri: 'https://auth.myapp.com/.well-known/jwks.json',
jwtOptions: {
algorithms: ['RS256'],
issuer: 'https://auth.myapp.com',
audience: 'https://api.myapp.com',
},
},
})
gateway.addRoute({
pattern: '/api/public/*',
target: 'http://public-api:3000',
auth: {
// Static API keys
apiKeys: ['key1', 'key2', 'key3'],
apiKeyHeader: 'x-api-key',
// Dynamic API key validation
apiKeyValidator: async (key, req) => {
const user = await validateApiKey(key)
if (user) {
// Attach user info to request
;(req as any).user = user
return true
}
return false
},
},
})
gateway.addRoute({
pattern: '/api/hybrid/*',
target: 'http://hybrid-service:3000',
auth: {
// JWT authentication
secret: process.env.JWT_SECRET,
jwtOptions: {
algorithms: ['HS256'],
issuer: 'https://auth.myapp.com',
},
// API key fallback
apiKeys: async (key, req) => {
return await isValidApiKey(key)
},
apiKeyHeader: 'x-api-key',
// Custom token extraction
getToken: (req) => {
return (
req.headers.get('authorization')?.replace('Bearer ', '') ||
req.headers.get('x-access-token') ||
new URL(req.url).searchParams.get('token')
)
},
// Custom error handling
unauthorizedResponse: {
status: 401,
body: { error: 'Authentication required', code: 'AUTH_REQUIRED' },
headers: { 'Content-Type': 'application/json' },
},
},
})
gateway.addRoute({
pattern: '/oauth/*',
target: 'http://oauth-service:3000',
auth: {
jwksUri: 'https://accounts.google.com/.well-known/jwks.json',
jwtOptions: {
algorithms: ['RS256'],
issuer: 'https://accounts.google.com',
audience: 'your-google-client-id',
},
// Custom validation
onError: (error, req) => {
console.error('OAuth validation failed:', error)
return new Response('OAuth authentication failed', { status: 401 })
},
},
})
# Using Bun (recommended)
bun add bungate
# Using npm
npm install bungate
# Using yarn
yarn add bungate
# Create a new project
mkdir my-gateway && cd my-gateway
bun init
# Install BunGate
bun add bungate
# Create your gateway
touch gateway.ts
import { BunGateway, BunGateLogger } from 'bungate'
const logger = new BunGateLogger({
level: 'info',
format: 'pretty',
enableRequestLogging: true,
})
const gateway = new BunGateway({
server: { port: 3000 },
// Global authentication
auth: {
secret: process.env.JWT_SECRET,
jwtOptions: {
algorithms: ['HS256'],
issuer: 'https://auth.myapp.com',
},
excludePaths: ['/health', '/metrics', '/auth/*'],
},
// Enable metrics
metrics: { enabled: true },
// Enable logging
logger,
})
// Add authenticated routes
gateway.addRoute({
pattern: '/api/users/*',
target: 'http://user-service:3001',
rateLimit: {
max: 100,
windowMs: 60000,
},
})
// Add public routes with API key authentication
gateway.addRoute({
pattern: '/api/public/*',
target: 'http://public-service:3002',
auth: {
apiKeys: ['public-key-1', 'public-key-2'],
apiKeyHeader: 'x-api-key',
},
})
await gateway.listen()
console.log('π Bungate running on http://localhost:3000')
MIT Licensed - see LICENSE for details.
Built with β€οΈ by 21no.de for the JavaScript Community
π Homepage | π Documentation | π Issues | π¬ Discussions
FAQs
A high-performance HTTP gateway for Bun, designed for microservices and API gateways.
The npm package bungate receives a total of 7 weekly downloads. As such, bungate popularity was classified as not popular.
We found that bungate demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
/Security News
npm author Qixβs account was compromised, with malicious versions of popular packages like chalk-template, color-convert, and strip-ansi published.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.