node

Zero framework imports, by structural typing

The adapter imports nothing from express, fastify, or even node:http. It is written against structural types (NodeRequestLike, NodeResponseLike) that describe only what the adapter reads and writes. Any real Node request/response object satisfies them, so the gateway’s zero-external-deps invariant holds and no @types packages ride along.

Install & Express integration

terminalCopy

npm install @rebilder/gateway        # pnpm add / yarn add

server.tsCopy

import express from 'express'
import { createGatewayMiddleware } from '@rebilder/gateway/node'
import { gatewayConfig } from './gateway-config'   // same GatewayConfig as every adapter

const app = express()
app.use(createGatewayMiddleware(gatewayConfig))    // before your routes
// ... your existing routes serve HTML exactly as before

Semantics are handleRequest’s, mapped onto the middleware contract:

How the web-standard Request is built

The web-standard Request is built from the Node request: host from the Host header; protocol from x-forwarded-proto (first value, set by your proxy/LB) → Express’s req.protocol → socket.encrypted; and Express’s originalUrl preferred over url (mounted routers rewrite url; sources must see the real path). Repeated (array) headers are appended per value.

toWebRequest(nodeReq, options?) is exported for reuse if you want core handleRequest semantics against a raw Node request yourself, for custom servers and other frameworks.

Fastify

Two options, no fastify-specific code in the package:

Option A: @fastify/middieCopy

// Option A: Fastify's middleware compat layer (@fastify/middie)
import middie from '@fastify/middie'
await fastify.register(middie)
fastify.use(createGatewayMiddleware(gatewayConfig))

Option B: onRequest hookCopy

// Option B: a 3-line onRequest hook over the raw req/res (no plugin needed)
const gateway = createGatewayMiddleware(gatewayConfig)
fastify.addHook('onRequest', (req, reply, done) => {
  gateway(req.raw, reply.raw, done) // markdown answered on res; otherwise done() continues
})

With Option B, Fastify’s routing never sees gateway-answered requests (the response is written on the raw socket), and every pass-through continues through done() into your normal routes.