Skip to content

7.0.0

Latest

Choose a tag to compare

@kartikk221 kartikk221 released this 15 Jul 21:11

HyperExpress v7.0.0

HyperExpress v7 modernizes the uWebSockets.js foundation while preserving the library's CommonJS packaging, snake_case API, route overloads, and performance-oriented execution model. This release focuses on predictable request, response, middleware, multipart, file, WebSocket, and server lifecycles under real backpressure and failure conditions.

Highlights

  • Updated to uWebSockets.js v20.69.0.
  • Added support for Node.js 22, 24, and 26.
  • Added router-scoped error and not-found handlers with nested-router precedence.
  • Rebuilt request body and multipart handling around uWebSockets.js onDataV2.
  • Hardened Node.js readable/writable piping and HTTP/WebSocket backpressure behavior.
  • Added stable upstream APIs for remote ports, response begin_write(), worker descriptors, WebSocket options, and WebSocket events.
  • Corrected response completion, streaming, files, cookies, JSONP, SSE, and server shutdown lifecycle races.
  • Expanded runtime, load, backpressure, regression, and TypeScript test coverage.

Runtime and platform support

HyperExpress v7 supports:

  • Node.js 22
  • Node.js 24
  • Node.js 26
  • Linux with glibc, macOS, and Windows

Plain musl Alpine and Alpine with gcompat are not supported. The upstream native addon can terminate with SIGSEGV in that environment; use a glibc-based image such as Debian or Ubuntu.

Middleware and routing

Middleware completion is now deterministic and guarded:

  • Synchronous middleware must call next().
  • Middleware returning any thenable advances when fulfilled.
  • Thrown errors, rejected thenables, next(error), and thenables fulfilled with an Error use the applicable error handler.
  • Each middleware advances at most once.
  • The accepted first next() call returns true; duplicate calls return false.
  • strict_middleware: true reports duplicate completion without advancing twice.

Routers now expose set_error_handler() and set_not_found_handler(). Errors resolve from the innermost mounted router through its parents to the server. Not-found handling uses the longest matching mount boundary with deterministic mount-order fallback.

Route registration now validates missing handlers, invalid middleware arrays, ambiguous option objects, and native registration inputs earlier. CONNECT routing, mount path boundaries, middleware propagation, registration order, and zero-valued route options are corrected.

Request bodies and multipart

The request body lifecycle now uses one eagerly bound onDataV2 receiver with remaining-length-aware preallocation and limits.

  • Request.buffer(), text(), json(), and other body helpers share concurrent in-flight work and retain settled values for repeated access.
  • Falsey parser results are cached correctly.
  • Fixed-length, empty, and transfer-encoded bodies settle consistently.
  • Requests remain proper Node.js readable streams and can be piped into writable streams with pause/resume backpressure.
  • Body limits, aborts, and completion settle parsers once without unsafe late native access.
  • Multipart field/file handlers are serialized, may return arbitrary thenables, and are fully awaited.
  • Unconsumed multipart files are drained and Busboy, source, and handler errors propagate once.
  • The post-body resume timeout behind #350 is fixed.

Responses, streams, files, and SSE

  • Responses remain proper Node.js writable streams and accept ordinary readable.pipe(response) pipelines.
  • Backpressure, drain races, aborts, early source close, source errors, zero-length streams, and completion ordering are handled consistently.
  • Response completion is idempotent across send, streaming, abort, upgrade, and close paths.
  • HEAD, 1xx, 204, and 304 responses suppress prohibited payload bytes with correct bodyless header behavior.
  • Header lookup is case-insensitive and compatibility helpers remain chainable.
  • Response.header() still appends by default; pass true as the overwrite argument to replace values.
  • html(), json(), and jsonp() now emit explicit UTF-8 charsets. send() remains content-type-neutral.
  • Signed cookies, scoped same-name cookies, and option-preserving deletion are corrected.
  • JSONP callback names and attachment filenames are sanitized; JSONP without a callback falls back to JSON.
  • File caches are server-owned, watcher cleanup is deterministic, and LiveFile.close() is idempotent.
  • SSE formatting now handles multiline data, comments, empty values, IDs, events, injection boundaries, and backpressure while retaining the v6 connection headers.
  • Response.begin_write() exposes the upstream beginWrite() primitive.

WebSockets and server lifecycle

  • WebSocket fragment streaming attempts each fragment once, awaits the final fragment, supports empty messages, and settles on source or socket failure.
  • WebSocket writable streams correctly handle backpressure and repeated pipelines.
  • send() and ping() expose the native numeric status: 1 sent, 0 backpressure, and 2 dropped.
  • message_type: 'ArrayBuffer' retains the v6 zero-copy callback-lifetime behavior; ArrayBufferSafe opts into a retained copy.
  • Listener exceptions and rejected thenables reach the WebSocket error event and close with code 1011 when unhandled.
  • Added opt-in WebSocket options close_on_backpressure_limit, max_lifetime, and send_pings_automatically.
  • Added WebSocket dropped and subscription events and Websocket.remote_port.
  • Added Request.port, Request.proxy_port, Server.get_descriptor(), add_child_app_descriptor(), and remove_child_app_descriptor().
  • Listen, shutdown, and close operations are idempotent. Graceful shutdown stops accepting and drains HTTP requests; force_close() explicitly closes all native sockets.

TypeScript

Existing routing overloads and middleware chaining forms are preserved. Declarations now match runtime behavior for streaming options, ArrayBuffer views, multipart results, router-scoped handlers, ports, descriptors, response lifecycle methods, and numeric WebSocket send statuses.

These corrections can reveal application code that depended on inaccurate v6 declarations.

Breaking changes

  • Node.js versions outside 22, 24, and 26 are no longer supported.
  • Alpine/musl deployments are unsupported, including Alpine with gcompat.
  • Thenable-returning middleware automatically advances when fulfilled; fulfilled Error values enter error handling.
  • Middleware cannot advance more than once, and next() now reports acceptance as a boolean.
  • WebSocket send() and ping() are typed as native numeric statuses rather than booleans.
  • Corrected TypeScript declarations may surface new compile-time errors in code relying on the old mismatches.
  • html(), json(), and jsonp() include explicit UTF-8 charsets.
  • Response lifecycle events, stream failures, bodyless statuses, multipart completion, and server shutdown now follow stricter deterministic semantics; code depending on previous races or invalid wire behavior may observe a change.

The WebSocket lifetime and backpressure-limit options remain opt-in. ArrayBuffer remains zero-copy by default, and Response.header() retains append-by-default behavior.

Resolved reports

  • #308: router-local error and not-found handlers
  • #322: fulfilled Error middleware handling
  • #334: helper content types and documented header policy
  • #345: buffer stress coverage and supported Linux environments
  • #348: current Node.js and uWebSockets.js support
  • #350: multipart post-body timeout
  • #351: duplicate middleware completion guard

Validation

The release is tested on Node.js 22, 24, and 26 across Linux, macOS, and Windows. The suite includes strict integration assertions, positive and negative TypeScript fixtures, slow request/response peers, aborted clients, concurrent multipart handlers, large Buffer and TypedArray payloads, Node stream piping, WebSocket fragment integrity, and sustained HTTP/WebSocket backpressure tests.

Upgrade

npm install hyper-express@7.0.0

Read the v6 to v7 migration guide before upgrading production applications.

Full changes: v6.18.0...v7.0.0