Skip to content

Express Integration ​

Use Wooks composables with Express. This adapter lets you register Wooks-style route handlers on top of an existing Express app — unmatched requests automatically fall through to Express middleware.

INFO

Source code and issues: github.com/wooksjs/express-adapter

Install ​

bash
npm install @wooksjs/express-adapter @wooksjs/event-http wooks express

Quick Start ​

ts
import express from 'express'
import { WooksExpress } from '@wooksjs/express-adapter'
import { useRouteParams, useRequest, HttpError } from '@wooksjs/event-http'

const app = express()
const wooks = new WooksExpress(app)

// Return values become the response body
wooks.get('/hello/:name', () => {
    const { get } = useRouteParams()
    return { hello: get('name') }
})

// Async handlers work out of the box
wooks.post('/upload', async () => {
    const { rawBody } = useRequest()
    const body = await rawBody()
    return { received: body.length }
})

// Throw HttpError for error responses
wooks.get('/protected', () => {
    throw new HttpError(403, 'Forbidden')
})

app.listen(3000, () => console.log('listening on 3000'))

How It Works ​

WooksExpress extends WooksHttp and registers itself as Express middleware. When a request comes in:

  1. Wooks checks if a matching route is registered
  2. If matched — the Wooks handler runs with full composable support
  3. If not matched — the request falls through to the next Express middleware

This means you can mix Wooks routes with regular Express routes and middleware:

ts
import express from 'express'
import { WooksExpress } from '@wooksjs/express-adapter'
import cors from 'cors'

const app = express()

// Express middleware works as usual
app.use(cors())

// Wooks handles these routes
const wooks = new WooksExpress(app)
wooks.get('/api/users', () => {
    return [{ id: 1, name: 'Alice' }]
})

// Body parsing for Express routes — register after WooksExpress
app.use(express.json())

// Express handles this route
app.get('/legacy', (req, res) => {
    res.send('handled by express')
})

app.listen(3000)

Register WooksExpress before body parsers

Body-parsing middleware (express.json(), body-parser) consumes the request stream — if it runs before Wooks, rawBody() / useBody() receive an empty body on Wooks routes. Instantiate WooksExpress before registering body parsers. Wooks parses bodies on demand, so global body parsers are unnecessary for Wooks routes.

API ​

new WooksExpress(expressApp, options?) ​

Creates a new adapter instance and registers Wooks middleware on the Express app.

OptionTypeDefaultDescription
raise404booleanfalseReturn 404 from Wooks for unmatched routes instead of falling through to Express
onNotFound() => unknown—Custom handler for unmatched routes
loggerTConsoleBase—Custom logger instance
routerobject—Router options (ignoreTrailingSlash, ignoreCase, cacheLimit)
requestLimitsobject—Default request body size limits
defaultHeadersRecord<string, string>—Headers added to every response
responseClasstypeof WooksHttpResponse—Custom response class, see Error Responses

Route Methods ​

ts
wooks.get(path, handler)
wooks.post(path, handler)
wooks.put(path, handler)
wooks.patch(path, handler)
wooks.delete(path, handler)
wooks.head(path, handler)
wooks.options(path, handler)
wooks.all(path, handler)

Handlers take no arguments — use composables to access request data:

ts
wooks.get('/users/:id', () => {
    const { get } = useRouteParams()
    const { method, url, rawBody, getIp } = useRequest()
    const headers = useHeaders()
    const response = useResponse()

    response.setHeader('x-custom', 'value')
    return { id: get('id') }
})

wooks.listen(port) ​

Starts the Express server and returns a promise that resolves when listening.

ts
await wooks.listen(3000)

wooks.close() ​

Stops the server. Only stops servers started via wooks.listen() — if you start the server with app.listen() yourself, keep the returned Server and close it directly (or pass it to wooks.attachServer(server) first).

ts
await wooks.close()

Available Composables ​

All @wooksjs/event-http composables work inside Wooks handlers — see the Composables reference.

Released under the MIT License.