Skip to content

Dev: let Electron orchestrate random ports for server + Vite #54

Description

@AntonNiklasson

Problem

pnpm dev runs three things concurrently on hardcoded ports — server on 7100, Vite on 7200, Electron pointing at 7200. If a stale pnpm dev instance is still running (easy to forget across terminals/IDE windows), a new one fails with a cryptic EADDRINUSE stack.

The packaged desktop build already grabs a random port via findFreePort() in packages/desktop/src/main.ts and the frontend doesn't need to know it (Hono serves the web bundle on the same origin in packaged mode, and Vite proxies /api in dev — either way React just calls relative /api/... URLs).

Proposal

Make Electron the dev orchestrator so dev mirrors packaged:

  • pnpm dev becomes pnpm --filter @github-dashboard/desktop dev (Electron is the only entry point).
  • Electron main, in dev mode, picks two free ports, then spawns:
    • the server as a child with PORT=<srv>
    • Vite as a child with --port <web> and GHD_API_PORT=<srv>
  • packages/web/vite.config.ts reads GHD_API_PORT for server.proxy['/api'].target.
  • Electron waits for both, then loadURL("http://localhost:<web>").

Consequences

  • No more port conflicts between concurrent pnpm dev instances — each gets a fresh pair.
  • Dev and packaged orchestration live in one file (main.ts).
  • The non-Electron browser dev workflow (point Chrome at localhost:7200) goes away. Acceptable — the primary dev surface is the desktop app.
  • CLAUDE.md validation guidance needs updating (no more fixed 7100/7200 in dev).

Open questions

  • Tooling like the Playwright MCP currently assumes http://localhost:7200. We'd need a stable way to discover the current dev URL — e.g. write .logs/ports.json on startup.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions