Coming from Express?
You already know bunWay. Same (req, res, next) signature, same middleware names, same routing patterns. Three things change on the way in:
1Change the import
require() → import2Rename the factory
express() → bunway()3Delete npm middleware26 built-ins ship with bunWay — no installs needed
26Built-in middleware
0npm dependencies
~1.6×Faster than Express
The Diff
Here's a real Express app migrated to bunWay. Every unmarked line is untouched.
js
const express = require('express')
const cors = require('cors')
const helmet = require('helmet')
const morgan = require('morgan')
import { bunway, cors, helmet, logger, json, session } from 'bunway'
const app = express()
const app = bunway()
app.use(cors())
app.use(helmet())
app.use(morgan('dev'))
app.use(logger('dev'))
app.use(express.json())
app.use(json())
app.use(session({ secret: 'keyboard cat' }))
app.get('/users/:id', (req, res) => {
res.json({ id: req.params.id })
})
app.listen(3000)What's Different
Only two things change
- ES modules only — use
importinstead ofrequire(). bunWay is TypeScript-first and ships no CommonJS build. - Bun runtime — run with
bun server.tsinstead ofnode server.js.
The handler signature (req, res, next), every method, every property — identical.
Middleware Replacements
Delete the npm package and update the import. The API is identical unless noted in the full reference below.
Body Parsing
express.json()→json()express.urlencoded()→urlencoded()body-parser.text()→text()body-parser.raw()→raw()Security
helmet→helmet()express-rate-limit→rateLimit()csurf→csrf()hpp→hpp()express-session→session()cookie-parser→cookieParser()Files & Assets
express.static()→serveStatic()multer→upload()serve-favicon→favicon()compression→compression()Observability & Utilities
morgan→logger()response-time→responseTime()express-request-id→requestId()method-override→methodOverride()connect-timeout→timeout()cors→cors()express-validator→validate()express-sse→sse()custom 4-arg middleware→errorHandler()API Reference
The request and response objects are 1:1 with Express. Open any section — identical means zero code changes, enhanced means bunWay is a superset.
Request — properties
| Property | Status |
|---|---|
req.params | identical |
req.query | identical |
req.body | identical |
req.cookies | identical |
req.path | identical |
req.method | identical |
req.ip | identical |
req.session | identical |
req.protocol | identical |
req.secure | identical |
Request — methods
| Method | Status | Notes |
|---|---|---|
req.get(header) | identical | |
req.fresh / req.stale | identical | ETag + Last-Modified cache validation |
req.range(size) | identical | Range header parsing |
req.param(name) | identical | params → body → query |
req.acceptsCharsets() | identical | |
req.acceptsEncodings() | identical | |
req.acceptsLanguages() | identical | |
req.is(type) | enhanced | Supports text/* and application/* wildcards |
req.accepts(type) | enhanced | RFC 7231 quality-value parsing |
Response — methods
| Method | Status | Notes |
|---|---|---|
res.json() | identical | |
res.send() | enhanced | Auto content-type detection + chainable |
res.status() | identical | |
res.set() | identical | |
res.cookie() | identical | |
res.redirect() | identical | |
res.sendStatus() | identical | |
res.sendFile() | enhanced | Automatic 206 Partial Content |
res.jsonp() | identical | |
res.download() | enhanced | Optional error callback |
res.attachment() | enhanced | Auto content-type detection |
res.end() | enhanced | Encoding + callback support |
Routing & server
| API | Status | Notes |
|---|---|---|
app.get/post/put/delete() | identical | |
app.use() | identical | Array path mounting supported |
app.route(path) | identical | Chainable route definitions |
import { Router } from "bunway" | identical | Was express.Router() |
Router({ mergeParams: true }) | identical | |
req.res / res.req | identical | Cross-references set during dispatch |
res.app | identical | |
| Regex routes | new | app.get(/\/fly$/, handler) |
app.all('*', handler) | identical | |
| Sub-app mounting | enhanced | app.mountpath + app.path() |
app.listen({ tls: opts }) | enhanced | Native TLS — no https.createServer() |
app.close(cb) | identical |
Ready? Get started → or jump straight to Middleware →