Skip to content

Migrating from Express

BananaJS runs on Express — middleware, Request/Response, and ecosystem packages still work. For a step-by-step migration strategy, the repository includes docs/MIGRATION.md (incremental adoption, BananaRouter, testing).

Incremental mount with BananaRouter

Mount generated BananaJS routes under a prefix while legacy Express routes stay in place:

typescript
import express from 'express'
import { BananaRouter } from '@banana-universe/bananajs'
import { UserController } from './user.controller.js'

const app = express()
app.use(express.json())

const bananaRoutes = BananaRouter([UserController])
app.use('/api/v2', bananaRoutes)

app.get('/legacy', (_req, res) => res.send('ok'))

app.listen(3000)

BananaRouter is a function that returns an Express Router — use it directly with app.use. (The longer docs/MIGRATION.md example in-repo may still say new BananaRouter / .router; prefer the pattern above.)

What changes conceptually

Express habitBananaJS pattern
Manual router.get/post@Controller + @Get/@Post on class methods
Manual body/query validation@Body(schema) / @Query(schema) with validation
Ad-hoc res.status().json()BaseController.ok or SuccessResponse + send
Central if (err) in every handlerThrow ApiError subclasses + ErrorMiddleware

Codemod

The CLI includes bananajs migrate — Express route codemod that emits *.controller.ts starters (see CLI).

Tests

Use BananaTestApp from @banana-universe/bananajs/testing to hit your app over HTTP without binding a real port in every test.

Released under the MIT License.