Skip to content
Eugene Lazutkin edited this page Aug 8, 2026 · 2 revisions

Node & Express adapter

toNodeHandler(handler, options?) adapts the bundler core to the callback world: it returns (req, res, next?)duck-typed, so it serves bare node:http and Express alike (Express req/res are IncomingMessage/ServerResponse supersets; the module imports no framework).

import {createServer} from 'node:http';
import {createBundler} from 'double-meh-bundler';
import {toNodeHandler} from 'double-meh-bundler/node.js';

const bundle = toNodeHandler(createBundler({isUrlAcceptable: url => url.startsWith('/api/')}));

createServer((req, res) =>
  req.url.startsWith('/bundle') ? bundle(req, res) : fallthrough(req, res)
).listen(3000);

Express mounts it directly:

app.put('/bundle', toNodeHandler(createBundler({isUrlAcceptable})));

Options

Option Default Meaning
compress true gzip the envelope when the client's Accept-Encoding allows. Bare node:http has no compression-middleware idiom, and the compressed envelope is the bundle's whole payoff — so the adapter owns it. Turn it off when a reverse proxy or middleware compresses for you.

Streamed bundles

The adapter detects a +jsonl response and switches its gzip to Z_SYNC_FLUSH, so each part reaches the client as it is written. This is not optional tuning — with the default flush mode gzip buffers the whole stream and the streamed bundle arrives all at once, which looks exactly like a working stream until you measure it.

The flush is what costs bytes: +25% at 10 parts, +57% at 50 (see Wire format § The compression trade). Buffered +json responses are untouched and keep the one-shot ratio.

Errors

With a next function supplied (Express style), errors are forwarded to next(error). Without one, the adapter answers 500 application/problem+json itself.

See also: Koa adapter, Bundler core.

🔍 Search the wiki

double-meh-bundler

Start

API

Protocol

Project

Clone this wiki locally