Drop-in replacement. One import replaces 15+ npm packages.
Same (req, res, next). Zero rewrites.
import { bunway, cors, helmet, json, session } from 'bunway'
const app = bunway()
app.use(cors({ origin: true }))
app.use(helmet())
app.use(json())
app.use(session({ secret: 'keyboard cat' }))
app.get('/users/:id', (req, res) => {
res.json({ id: req.params.id })
})
app.post('/users', validate({
body: { email: { required: true, type: 'email' } }
}), createUser)
app.listen(3000)
// That's it. No npm install. No config.What's inside
Every package Express developers reach for — already inside bunWay. No npm install. No version conflicts. No supply chain risk.
import { bunway, helmet, cors, csrf, rateLimit, hpp } from 'bunway'
const app = bunway()
app.use(helmet()) // 14 security headers
app.use(cors({ origin: /\.myapp\.com$/ })) // CORS + preflight
app.use(rateLimit({ windowMs: 60_000, max: 100 }))
app.use(csrf()) // double-submit cookie
app.use(hpp({ whitelist: ['tags'] })) // parameter pollutionReal-world patterns
REST APIs, WebSocket servers, file upload endpoints — bunWay handles them all. One import. No plugins.
REST API
Validation · rate limiting · CORS
import { bunway, json, cors,
rateLimit, validate } from 'bunway'
const app = bunway()
app.use(cors(), json())
app.use(rateLimit({ max: 100 }))
app.post('/users',
validate({ body: {
email: { required: true, type: 'email' }
}}),
(req, res) => res.json({ ok: true })
)
app.listen(3000)Real-time WebSocket
Native Bun WS · no extra packages
import { bunway } from 'bunway'
const app = bunway()
app.ws('/live', {
open(ws) {
ws.send('connected')
},
message(ws, msg) {
ws.send(`echo: ${msg}`)
},
close(ws) {}
})
app.listen(3000)
// ws://localhost:3000/liveFile Upload & Serve
Uploads · static serving · ETag caching
import { bunway, upload,
serveStatic } from 'bunway'
const app = bunway()
const store = upload()
app.use('/files', serveStatic('./uploads'))
app.post('/upload',
store.single('photo'),
(req, res) => res.json({
name: req.file?.originalname
})
)
app.listen(3000)Express → bunWay
Everything else stays exactly the same. No rewrites, no new patterns to learn.
$ npm install express $ npm install cors helmet $ npm install express-session $ npm install morgan compression $ npm install express-rate-limit $ ...9 more packages + 26 transitive dependencies
const express = require('express')
const cors = require('cors')
const helmet = require('helmet')
const session = require('express-session')
// 10 more require() calls...$ bun add bunway # that's it.
import { bunway, cors, helmet,
session } from 'bunway'
// cors, helmet, session already inside
// nothing else to installEverything below stays identical
const app = bunway() // was: express()
app.use(cors())
app.use(helmet())
app.use(session({ secret: 'keyboard cat' }))
app.get('/users/:id', (req, res) => {
res.json({ id: req.params.id })
})
app.listen(3000)Start now
One command. No config. Your Express app runs on Bun today.