@hoajs/adapter
This package provides an adapter that lets a Hoa application run seamlessly on a Node.js HTTP server. Under the hood it uses createServerAdapter from @whatwg-node/server to bridge WHATWG Fetch–style Request/Response with Node's http.Server.
Quick Start
import { Hoa } from 'hoa'
import { nodeServer } from '@hoajs/adapter'
const app = new Hoa()
app.extend(nodeServer())
app.use(async (ctx) => {
ctx.res.body = 'Hello, Hoa!'
})
app.listen(3000, () => {
console.log('Listening on 3000')
})app.listen
Hoa's app.listen delegates to Node's server.listen(...) and supports the same call signatures. See the official Node.js docs: server.listen()
app.listen(handle[, backlog][, callback])
app.listen(options[, callback])
app.listen(path[, backlog][, callback])
app.listen([port[, host[, backlog]]][, callback])app.callback
app.callback() returns a Node.js request listener (req, res) => void backed by the same WHATWG Fetch adapter that powers app.listen. Use it when you want to mount Hoa inside an existing http.Server, integrate with testing libraries such as supertest, or wrap the listener with custom server logic.
import { createServer } from 'http'
import { Hoa } from 'hoa'
import { nodeServer } from '@hoajs/adapter'
const app = new Hoa()
app.extend(nodeServer())
app.use(async (ctx) => {
ctx.res.body = 'Hello, Hoa!'
})
const server = createServer(app.callback())
server.listen(3000)Testing with supertest
app.callback() is the recommended entry point for HTTP-level testing without binding to a real port:
import request from 'supertest'
import { Hoa } from 'hoa'
import { nodeServer } from '@hoajs/adapter'
const app = new Hoa()
app.extend(nodeServer())
app.use(async (ctx) => {
ctx.res.body = 'Hello, Hoa!'
})
await request(app.callback())
.get('/')
.expect(200, 'Hello, Hoa!')Note:
app.callback()andapp.listen()share the same underlying adapter, so behavior is identical. The only difference is thatapp.callback()does not start a server — you are responsible for binding it withhttp.createServer,https.createServer, or a test harness.
Node.js interoperability
Hoa works with web-standard body types (e.g. string, Blob, ArrayBuffer, TypedArray, ReadableStream). When returning Node.js primitives, you may need to convert them into their web equivalents:
- Buffer → ArrayBuffer (Optional)
- Node.js Readable stream → Web
ReadableStream
Example: Buffer to ArrayBuffer
app.use(async (ctx) => {
const buf = Buffer.from('Hello, Hoa!')
// Convert Buffer to ArrayBuffer
const arrayBuffer = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength)
ctx.res.body = arrayBuffer
// ctx.res.body = buf // buf is a Uint8Array instance and also works directly
})Example: Node.js stream to Web ReadableStream
import { Readable } from 'node:stream'
app.use(async (ctx) => {
const nodeStream = Readable.from(['Hello, ', 'Hoa!'])
// Convert Node.js Readable stream to Web ReadableStream
const webStream = Readable.toWeb(nodeStream)
ctx.res.body = webStream
})