Beadbox: Full Next.js + WebSocket server running as Tauri v2 sidecar #15049
nmelo
started this conversation in
Show and tell
Replies: 1 comment
-
|
Packaging a full Next.js SSG + WebSocket via a sidecar is an interesting approach to Tauri! Just be careful with port collisions; it's best to dynamically allocate an open port for the WS server at runtime and pass it back to the Tauri frontend via IPC rather than hardcoding port 3000. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
We built Beadbox, a native desktop app using Tauri v2 that bundles a full Next.js server + WebSocket server as sidecar processes.
Why Tauri + sidecar
We had a working Next.js app with server components, server actions, and a WebSocket server for real-time updates. Rewriting that in Rust would have meant months of work. With the sidecar pattern, we kept our entire Node.js stack and just wrapped it.
This also let us move fast: we develop with multiple AI coding agents working in parallel, coordinated through beads (the issue tracker Beadbox is built for). One agent handles the Next.js frontend, another works on the WebSocket server, a third writes tests. Having real-time visibility into what all your agents are doing is actually why Beadbox exists — you need a dashboard when you have 8 agents shipping code simultaneously.
The pattern
Rust spawns two child processes at startup:
node server.js(Next.js standalone server)node ws-server.js(WebSocket for real-time updates)The WebView points at
localhost:{port}. The web app doesn't know it's inside Tauri.Gotchas we solved
Zombie processes: Force-quit or crash leaves Node processes running. On Unix:
setpgid+killpgon SIGTERM/SIGINT/SIGHUP, plus a Drop impl. On Windows: Job Objects withKILL_ON_JOB_CLOSE.macOS PATH is empty in GUI apps: Homebrew doesn't exist from inside a Tauri app (
PATH=/usr/bin:/bin:/usr/sbin:/sbin). Fix: spawn the user's login shell at startup, capture its PATH, inject into child process env.NEXT_PUBLIC_ vars are baked at build time: Our WebSocket port is assigned dynamically by Rust, but the client bundle was compiled with a static port. We hardcode the WS port now.
Intel Mac Homebrew Node is a stub: It's dynamically linked against
/usr/local/opt/libraries. Our build script runsotool -Land downloads a standalone binary from nodejs.org if it detects non-system deps.Result
The app is a GUI for the beads issue tracker. Real-time sync, epic tree views, dependency badges, multi-workspace.
brew tap beadbox/cask && brew install --cask beadboxOr download from https://beadbox.app — free during beta.
Beta Was this translation helpful? Give feedback.
All reactions