How it's built
Measured at every layer, fixed where the problem is.
Most of Fulmine's speed is not ours. µWebSockets.js does the network work and matches routes in C++. Fulmine's part is to give it every route it can, and to answer the simple ones without going back to JavaScript. This is where the big numbers on the performance page come from.
A request also goes through Node.js, the µWS binding and the µWS server. When a measure found a problem in one of them, we fixed it there, with a pull request and its benchmark. Below there is one fact for each layer, with the link to check it.
Node.js
- A call from native code into JavaScript (
MakeCallback, Node-API,AsyncWrap) went from 202-208 ns to 155-159 ns. nodejs/node#66316, landed on 29 September 2026. - From Node 24,
AsyncLocalStoragelost its store in the callbacks ofnode::AsyncResource. Now it keeps it, and the call is 29% to 36% faster. nodejs/node#66326, merged on 14 October 2026.
µWebSockets.js
Fulmine pins the installable binaries commit ea0d00dd9a45b76fa89a9609116973fe5794fc3c. Its source_commit identifies source 139419cece198053af3478e4a367ecac4e006bb9, from 16 October 2026. Upstream's package version remains 20.71.0; these commits include changes made after the v20.71.0 release tag. The measurements below belong to the linked upstream changes, not to a comparison of Fulmine builds.
Fifteen pull requests merged. Some of them:
res.onAbortedfrom 91 ns to 45 ns per call: #1330, #1331.- Strings written as UTF-8 in one pass: a 200 KB ASCII body from 12.0 µs to 6.9 µs. #1335, #1337.
- A crash when a string filled the 128 KB pool and the next one was empty, also in v20.71.0. #1338.
- Every pull request is now benchmarked against its base branch in CI. #1326.
µWebSockets
Four fixes to HTTP/1.1 conformance: a Host header with a path is refused, a bare LF in the trailers is a 400, a request target that is not visible ASCII is a 400, and OPTIONS * is accepted. #1949, #1950, #1951, #1952.
µWebSockets and µWebSockets.js are the work of Alex Hultman (uNetworking), who reviewed and merged these changes.
Fulmine
Here is where the multiples are. Routes go to µWS's router and are matched in C++, so the gap with Express grows with the route table instead of shrinking. A handler simple enough is compiled into a µWS declarative response, and µWS answers it without entering JavaScript. Every change on the request path comes with a CPU profile against the commit before it, see benchmark/README.md.
Who
Fulmine is maintained by Simone Nigro. The rest of the open source work is on sndesign.it.