Skip to content

fix(dev): make bun dev work on Windows without dropping the PORT override - #587

Merged
Aymericr merged 1 commit into
mainfrom
fix/windows-dev-scripts
Aug 4, 2026
Merged

fix(dev): make bun dev work on Windows without dropping the PORT override#587
Aymericr merged 1 commit into
mainfrom
fix/windows-dev-scripts

Conversation

@Aymericr

@Aymericr Aymericr commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Fixes the Windows dev-server breakage reported in #551, keeping the PORT override that both SETUP.md and .env.example document.

The bugs

Two package scripts use POSIX shell syntax Bun's own shell doesn't implement — and Bun uses that shell for bun run on Windows:

  1. apps/editor dev script passes --port ${PORT:-3002}, which reaches Next verbatim:
    error: option '-p, --port <port>' argument '${PORT:-3002}' is invalid.
    
  2. Root dev script starts set -a && . ./.env, and set isn't a Bun shell builtin — it prints bun: command not found: set and silently skips loading .env altogether.

Both reproduce on macOS with bun run --shell=bun, which selects the same shell Windows gets:

$ echo port=${PORT:-3002}
port=${PORT:-3002}          # unexpanded even with PORT=9999 in the environment
$ set -a && echo set-worked
bun: command not found: set

Worth noting the second one is a silent failure: turbo still runs, so on Windows the root .env has simply never been loaded and nothing said so.

The fix

Hardcoding --port 3002 fixes Windows but drops the documented PORT override. Instead, load a committed .env.defaults last and let next dev read PORT from the environment — its CLI already declares .env('PORT') on the -p, --port option:

-"dev": "dotenv -e ../../.env.local -- next dev --port ${PORT:-3002}",
+"dev": "dotenv -e ../../.env.local -e ../../.env.defaults -- next dev",
-"dev": "set -a && . ./.env 2>/dev/null; set +a; turbo run dev --env-mode=loose",
+"dev": "dotenv -e ./.env -e ./.env.defaults -- turbo run dev --env-mode=loose",

Nothing is shell-expanded, so behaviour is identical on every platform. .env.defaults exists because .env and .env.local are gitignored — a checked-in default has nowhere else to live.

No --hostname is added: Next deliberately passes no default host, Node then binds :: dual-stack, and pinning 0.0.0.0 would make http://[::1]:3002 unreachable.

Verification

Precedence is shell PORT > .env.local > .env.defaults, confirmed under both shells:

scenario shell result
default --shell=bun (Windows path) http://localhost:3002
PORT=4321 --shell=bun http://localhost:4321
default system (macOS/Linux) http://localhost:3002
root bun dev --shell=bun turbo runs, no command not found: set

Gates: check clean (1600 files) · check-types 9/9 · test 1881 pass / 0 fail · build 7/7.

Also corrects .env.example, which advertised a 3000 default the repo hasn't used since the port moved to 3002.

Credit

Reported by @evolv3ai in #551, including the Windows console output and the set finding — both reproduced here. That PR also proposed two other changes; #578 has since fixed the autosave-guard one at the hook layer, and the third turned out to be a non-issue (apps/editor/next.config.ts already redirects /editor/:id/scene/:id).

Supersedes #551.

🤖 Generated with Claude Code


Note

Low Risk
Dev-only script and env loading changes; no runtime app logic, auth, or production deployment paths affected.

Overview
Fixes Windows bun run dev failures caused by POSIX-only shell syntax in package scripts.

Editor dev no longer passes --port ${PORT:-3002} (Bun’s shell leaves that literal and breaks Next). It now runs dotenv with ../../.env.local and ../../.env.defaults, then next dev, so PORT comes from the environment (default 3002 in the committed defaults file).

Root bun dev no longer uses set -a && . ./.env (unsupported on Bun’s Windows shell, which silently skipped loading .env). It uses dotenv -e ./.env -e ./.env.defaults before turbo run dev.

Adds .env.defaults documenting precedence: shell PORT > .env.local > defaults. .env.example is updated to document port 3002 instead of 3000.

Reviewed by Cursor Bugbot for commit 2f4a229. Bugbot is set up for automated code reviews on this repo. Configure here.

…ride

Two package scripts use POSIX shell syntax that Bun's own shell does not
implement, and Bun uses that shell for `bun run` on Windows:

- `apps/editor`'s dev script passes `--port ${PORT:-3002}`, which arrives at
  Next verbatim: `option '-p, --port <port>' argument '${PORT:-3002}' is
  invalid`. Setting PORT does not help — the literal is never expanded.
- the root dev script starts `set -a && . ./.env`, and `set` is not a Bun
  shell builtin, so it prints `bun: command not found: set` and silently
  skips loading `.env` entirely.

Reproduced both on macOS with `bun run --shell=bun`, which selects the same
shell Windows gets:

    $ echo port=${PORT:-3002}
    port=${PORT:-3002}          # even with PORT=9999 in the environment
    $ set -a && echo set-worked
    bun: command not found: set

Hardcoding the port would fix Windows but drop the PORT override that
SETUP.md and .env.example both document. Instead, load a committed
`.env.defaults` last and let `next dev` read PORT from the environment
(the CLI already declares `.env('PORT')` on `-p, --port`). Nothing is
shell-expanded, so it behaves the same on every platform, and the
precedence stays shell PORT > .env.local > .env.defaults — verified at
3002 by default and 4321 with an override, under both shells.

`.env.defaults` is needed because `.env` and `.env.local` are gitignored,
so a checked-in default has nowhere else to live.

Also corrects `.env.example`, which advertised a 3000 default the repo has
not used since the port moved to 3002.

Reported by @evolv3ai in #551, including the Windows console output and the
`set` finding.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Aymericr
Aymericr merged commit b888f13 into main Aug 4, 2026
3 checks passed
@Aymericr
Aymericr deleted the fix/windows-dev-scripts branch August 4, 2026 22:02

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2f4a229. Configure here.

Comment thread package.json
"scripts": {
"build": "turbo run build",
"dev": "set -a && . ./.env 2>/dev/null; set +a; turbo run dev --env-mode=loose",
"dev": "dotenv -e ./.env -e ./.env.defaults -- turbo run dev --env-mode=loose",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Root defaults block local PORT

Medium Severity

The dev script loads .env.defaults via dotenv-cli before the editor application starts. This causes PORT values from .env.local to be ignored by the editor, as dotenv-cli does not override existing environment variables, breaking the intended precedence.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2f4a229. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant