WebSocketError: Connection refused in bun `--bun` runtime
[UPDATED]
Environment
- Operating System: Darwin
- Node Version: v22.14.0
- Nuxt Version: -
- CLI Version: 3.22.5
- Nitro Version: 2.11.1
- Package Manager: [email protected]
- Builder: -
- User Config: -
- Runtime Modules: -
- Build Modules: -
bun 1.2.4
Reproduction
https://github.com/jamaluddinrumi/can-not-send-anything-websocket
or
just start with starter template
follow websocket usage
run
bun --bun run dev
and type in the terminal, i use websocat tool to checking the websocket logs
websocat ws://localhost:3000 -v
it returns
[INFO websocat::lints] Auto-inserting the line mode
[INFO websocat::stdio_threaded_peer] get_stdio_peer (threaded)
[INFO websocat::ws_client_peer] get_ws_client_peer
[INFO websocat::net_peer] Failure during connecting TCP: Connection refused (os error 61)
websocat: WebSocketError: Connection refused (os error 61)
websocat: error running
without received sent message Welcome ${peer}!
Describe the bug
it should sent Welcome ${peer}! message
Additional context
No response
Logs
but strangely, it works without --bun
bun run dev // without --bun
websocat ws://localhost:3000 -v
[INFO websocat::lints] Auto-inserting the line mode
[INFO websocat::stdio_threaded_peer] get_stdio_peer (threaded)
[INFO websocat::ws_client_peer] get_ws_client_peer
[INFO websocat::net_peer] Connected to TCP 127.0.0.1:3000
[INFO websocat::ws_client_peer] Connected to ws
{"user":"server","message":"Welcome 1216e950-8db1-4a38-9153-83bdde43f7be!"}
After some investigation, I believe this is an issue with Bun.
In dev mode (nitro dev), Nitro uses ws for WebSockets, and ws is primarily designed for Node.js. An issue in ws: https://github.com/websockets/ws/issues/2179 also points to the issue of Bun's compatibility with Node.js: https://github.com/oven-sh/bun/issues/6905 (Although this is closed, it doesn't seem to be completely fixed).
bun --bun run will force the CLI to run with Bun instead of Node.js. Therefore, this compatibility issue is amplified.
If nitro wants to fix this, it might have to switch to Bun.serve() in dev mode when --bun is used, but that doesn't seem worth it, since Bun should fix it...
Additionally, in production when built with preset: "bun", everything works fine. (Since we are using Bun.serve() in this condition)
Additionally, in production when built with
preset: "bun", everything works fine. (Since we are usingBun.serve()in this condition)
Does Nitro have this preset? Or do you mean using bun build --target bun?
Yes, Nitro has preset: "bun".
export default defineNitroConfig({
preset: "bun"
});
You can browse all the built-in presets here.
@kricsleo Unfortunately, even if there were fewer WebSocket connection errors, running bun --bun dev produces unusable HMR. Same as before: you can only see changes when you reload the page.
Additionally, I can see no messages posted in the WebSocket connection, it's pending.
On another thought, if Nitro runs Bun.serve(), I run bun dev, and it works, this should mean it's technically runs on Bun, because Node wouldn't know what's Bun.serve.
After some investigation, I believe this is an issue with
Bun.In dev mode (
nitro dev), Nitro uses ws for WebSockets, andwsis primarily designed for Node.js. An issue inws: websockets/ws#2179 also points to the issue ofBun's compatibility with Node.js: oven-sh/bun#6905 (Although this is closed, it doesn't seem to be completely fixed).
bun --bun runwill force the CLI to run withBuninstead of Node.js. Therefore, this compatibility issue is amplified.If
nitrowants to fix this, it might have to switch toBun.serve()in dev mode when--bunis used, but that doesn't seem worth it, sinceBunshould fix it...Additionally, in production when built with
preset: "bun", everything works fine. (Since we are usingBun.serve()in this condition)
As described before, --bun only works for production builds, not dev, due to Bun's compatibility issues with Node.js.