zoltraak-a-0.0.1
v0.1.0
Published
bun framework that make it use for me i didn't think now
Maintainers
Readme
Zoltraak
Ultra-performance secure web framework for Bun - 6-7x faster than Elysia
Zoltraak is a blazingly fast, security-first web framework built exclusively for Bun. It achieves near-native Bun performance while providing enterprise-grade security defaults and an elegant developer experience.
Features
- 🚀 Blazing Fast - 6-7x faster than Elysia, 33% of raw Bun.serve speed
- 🔒 Secure by Default - HSTS, XSS protection, CORS, rate limiting out of the box
- 📝 Type-Safe Validation - Built-in schema validation with TypeScript inference
- 🎯 Zero Dependencies - Pure TypeScript, no runtime dependencies
- ⚡ Compile-Time Optimization - Routes compiled at startup for maximum runtime performance
- 🛡️ Guards System - Composable middleware-like access control
- 🎨 Elegant API - Express-like API with modern TypeScript features
Performance
Benchmark results (50,000 requests, 20 concurrent connections):
╔═══════════════════════════════════════════════════════════════╗
║ BENCHMARK RESULTS ║
╠═══════════════════════════════════════════════════════════════╣
║ Simple endpoint: ║
║ Zoltraak vs Elysia: 6.70x faster ║
║ Zoltraak Fast vs Elysia: 7.28x faster ║
║ Zoltraak vs Baseline: 106% of raw Bun ║
║ ║
║ Path params: ║
║ Zoltraak vs Elysia: 7.30x faster ║
║ Zoltraak Fast vs Elysia: 7.74x faster ║
╚═══════════════════════════════════════════════════════════════╝See benchmarks/ for details.
Installation
bun add zoltraakRequirements: Bun 1.2.3 or higher
Quick Start
import { Zoltraak } from 'zoltraak'
const app = new Zoltraak()
// Simple route
app.get('/ping', () => new Response('pong'))
// Route with path parameters
app.get('/users/:id', (ctx) => {
return new Response(`User ID: ${ctx.params.id}`)
})
// JSON response
app.get('/api/hello', () => {
return new Response(
JSON.stringify({ message: 'Hello, World!' }),
{ headers: { 'Content-Type': 'application/json' } }
)
})
app.listen(3000)API Documentation
Application
Creating an App
import { Zoltraak } from 'zoltraak'
const app = new Zoltraak({
port: 3000,
hostname: '0.0.0.0',
security: {
headers: true, // Security headers (default: true)
bodyLimit: 1_048_576, // 1MB body limit (default)
timeout: 30_000, // 30s timeout (default)
rateLimit: {
maxRequests: 100, // Max requests per window
windowMs: 60_000, // Time window (1 minute)
}
}
})Route Registration
// HTTP methods
app.get(path, handler, guards?)
app.post(path, handler, guards?)
app.put(path, handler, guards?)
app.delete(path, handler, guards?)
app.patch(path, handler, guards?)
app.head(path, handler, guards?)
app.options(path, handler, guards?)
app.all(path, handler, guards?) // All HTTP methods
// Advanced route configuration
app.route({
path: '/users/:id',
method: 'GET',
handler: (ctx) => new Response('...'),
guards: [authGuard, adminGuard]
})Context
The context object provides access to request data:
app.get('/example', (ctx) => {
ctx.req // Raw Request object
ctx.params // Path parameters { id: "123" }
ctx.query // URLSearchParams (lazy-initialized)
ctx.url // URL object (lazy-initialized)
ctx.headers // Request headers
ctx.ip // Client IP address
ctx.server // Bun server instance
})Path Parameters
app.get('/users/:userId/posts/:postId', (ctx) => {
const { userId, postId } = ctx.params
return new Response(`User ${userId}, Post ${postId}`)
})Query Parameters
app.get('/search', (ctx) => {
const query = ctx.query.get('q')
const page = ctx.query.get('page') ?? '1'
return new Response(`Search: ${query}, Page: ${page}`)
})
// GET /search?q=test&page=2Type Validation
Zoltraak includes a built-in, lightweight validation system with TypeScript type inference:
import { parseBody, t } from 'zoltraak'
const userSchema = {
name: t.string({ minLength: 1, maxLength: 100 }),
email: t.string({ pattern: /^[^@]+@[^@]+$/ }),
age: t.optional(t.number({ min: 0, max: 150 })),
role: t.enum(['user', 'admin'] as const),
}
app.post('/users', async (ctx) => {
const data = await parseBody(ctx, userSchema)
// data is typed as:
// { name: string, email: string, age?: number, role: 'user' | 'admin' }
return new Response(JSON.stringify({ id: '123', ...data }), {
headers: { 'Content-Type': 'application/json' }
})
})Schema Types
t.string({
minLength?: number,
maxLength?: number,
pattern?: RegExp,
enum?: readonly string[]
})
t.number({
min?: number,
max?: number,
enum?: readonly number[]
})
t.boolean()
t.array(itemSchema)
t.object(propertiesSchema)
t.optional(schema) // Makes field optional
t.nullable(schema) // Allows null
t.enum(['a', 'b', 'c']) // Enum values
t.any() // Any typeValidation Functions
// Parse and validate request body
const data = await parseBody(ctx, schema)
// Validate query parameters
const query = validateQuery(ctx, schema)
// Validate path parameters
const params = validateParams(ctx, schema)
// Create reusable validator
const validator = createValidator(schema)
const data = validator(unknownData)Guards (Middleware)
Guards are composable functions that control access to routes:
import { type Guard } from 'zoltraak'
// Authentication guard
const authGuard: Guard = (ctx) => {
const token = ctx.headers.get('authorization')
return token === 'Bearer secret-token'
}
// Admin guard
const adminGuard: Guard = (ctx) => {
return ctx.headers.get('x-admin') === 'true'
}
// Use guards on routes
app.get('/protected', handler, [authGuard])
app.get('/admin', handler, [authGuard, adminGuard])
// Compose guards
import { composeGuards } from 'zoltraak'
const adminAuth = composeGuards(authGuard, adminGuard)
app.get('/admin', handler, [adminAuth])Rate Limiting Guard
import { createRateLimitGuard } from 'zoltraak'
const strictLimit = createRateLimitGuard({
maxRequests: 10,
windowMs: 60_000, // 10 requests per minute
})
app.get('/limited', handler, [strictLimit])Body Size Limit Guard
import { createBodyLimitGuard } from 'zoltraak'
const bodyLimit = createBodyLimitGuard(1024 * 1024) // 1MB
app.post('/upload', handler, [bodyLimit])Security Features
Security Headers (Enabled by Default)
Zoltraak automatically applies these security headers to all responses:
Strict-Transport-Security: max-age=31536000; includeSubDomainsX-Content-Type-Options: nosniffX-Frame-Options: DENYX-XSS-Protection: 1; mode=blockReferrer-Policy: strict-origin-when-cross-originPermissions-Policy: geolocation=(), microphone=(), camera=()
To disable for maximum performance:
const app = new Zoltraak({
security: { headers: false }
})Rate Limiting
Default rate limiting (100 requests per minute per IP):
const app = new Zoltraak({
security: {
rateLimit: {
maxRequests: 100,
windowMs: 60_000,
keyExtractor: (ctx) => ctx.ip ?? 'unknown'
}
}
})
// Disable rate limiting
const app = new Zoltraak({
security: { rateLimit: false }
})Body Size Limits
Default 1MB body size limit:
const app = new Zoltraak({
security: {
bodyLimit: 5 * 1024 * 1024 // 5MB
}
})Advanced Usage
Custom Error Handling
app.post('/users', async (ctx) => {
try {
const data = await parseBody(ctx, userSchema)
// Process data...
} catch (error) {
if (error instanceof ValidationError) {
return new Response(
JSON.stringify({ error: error.message, field: error.field }),
{ status: 400, headers: { 'Content-Type': 'application/json' } }
)
}
throw error
}
})Request Body Parsing
import { parseJsonWithLimit, parseTextWithLimit } from 'zoltraak'
app.post('/json', async (ctx) => {
const data = await parseJsonWithLimit(ctx, 1024) // 1KB limit
return new Response('OK')
})
app.post('/text', async (ctx) => {
const text = await parseTextWithLimit(ctx, 1024)
return new Response('OK')
})Performance Mode
For maximum performance, disable security features:
const app = new Zoltraak({
security: {
headers: false,
rateLimit: false,
}
})This can achieve 7.28x faster than Elysia and 106% of raw Bun.serve performance.
Architecture
Zoltraak uses a thin wrapper strategy over Bun's native routing:
User API (Zoltraak)
↓ compile at startup
Bun.serve({ routes })
↓ runtime
Native Bun HTTP handlingKey design principles:
- Compile-time composition - Routes and guards compiled into optimized functions at startup
- Zero runtime overhead - No middleware loops, direct function calls
- Lazy initialization - URL parsing, query params only computed when accessed
- Sync-first - Synchronous handlers avoid async/await overhead
- Pre-compiled extractors - Path parameter extraction optimized at startup
Examples
See examples/basic.ts for a comprehensive example including:
- Route registration
- Path parameters
- Query parameters
- Guards (authentication/authorization)
- JSON responses
- Rate limiting
- Body parsing with validation
Run the example:
bun run examples/basic.tsBenchmarking
Run benchmarks:
# Start all benchmark servers
bun run benchmarks/baseline.ts &
bun run benchmarks/zoltraak.ts &
bun run benchmarks/zoltraak-fast.ts &
bun run benchmarks/elysia.ts &
# Run benchmark
bun run benchmarks/stable-bench.tsContributing
Contributions are welcome! Please ensure:
- TypeScript strict mode passes:
bun run typecheck - All tests pass:
bun test - Benchmarks show no performance regression
License
MIT
Acknowledgments
Made with ⚡ by the Zoltraak team
