Appearance
Developing the Windows port from macOS
Maintainer reference for contributing to bunium's own Windows native layer from a Mac — not needed to use
buniumin an app.
Windows CEF can't run on macOS directly — and there's no Docker escape hatch: Docker Desktop on macOS only runs Linux containers, and MS Windows containers only ever run on Windows hosts. Apple-silicon Parallels/UTM Windows-on-ARM VMs emulate x64 apps but CEF's GPU/child-process stack is flaky under that emulation, so treat those as a "sometimes useful, never primary" option.
The workable model is a remote Windows runner with two tiers.
Tier 1 — per-PR smoke on GitHub Actions (primary)
.github/workflows/win-smoke.yml builds the native stack on windows-latest and runs examples/basic-window.ts as the smoke test. It needs no Visual Studio — clang-cl + the CEF distro only (see docs/guide/windows.md). Since Windows packaging landed, the same job also runs packaging/win/package.sh on the fixture app and verifies the packaged EXE end-to-end (opens a real window, pixel-checks the page, requires PACKAGED_APP_VERIFY:PASS) — so a mac dev gets Windows packaging CI coverage on every PR, not just the dev-tree build.
- Runs on every PR touching
native/**/src/**and onmain. - The CEF distro is git-ignored (388 MB), so the workflow downloads the pinned distro. Set a repo variable
CEF_ZIP_URL(Actions → Settings → Variables) to the exactcef_binary_*_windows64_minimal.zipURL matching the vendoredvendor/cef-windows-x64/include/cef_version.h; otherwise the job falls back to the same URL hardcoded in the workflow and fails early with instructions if it drifts. Find the URL at https://cef-builds.spotifycdn.com/ (Windows 64-bit, Minimal Distribution). - Native artifacts and CEF logs are uploaded as workflow artifacts so a mac dev can download and inspect them without a Windows box.
Tier 2 — SSH remote runner (ad-hoc iteration)
For times when a PR won't cut it (iterating on a Windows-only crash, watching live logs), run a Windows machine — a cloud VM or an old laptop — and use scripts/win-remote.sh:
sh
# one-time: push the tree incl. the CEF distro and build remotely
scripts/win-remote.sh push hostname@windows-host
# iterate: sync + build + run the smoke, streaming logs back to your mac
scripts/win-remote.sh smoke hostname@windows-host
# packaging: sync + build + package + verify the packaged app end-to-end
scripts/win-remote.sh pack hostname@windows-hostThe script assumes Git Bash + LLVM's clang-cl are on the remote host (PATH-reachable), rsync over ssh, and that vendor/cef-windows-x64 is in the pushed tree (CEF is git-ignored — this is the one thing push carries explicitly). Run win-remote.sh --help for details.
Always reproduce locally first
Whatever the remote story, a Windows dev box remains the source of truth. The escape hatches that worked during bring-up (--single-process, GPU feature flags) were diagnostics only — multi-process works now; don't paper over child-process issues with single-process hacks (bun + in-process CEF SEGVs).
Quick checklist when a child misbehaves
- Rebuild once (
bash native/win/build.sh) — stale wrapper/dll copies hide undernative/build/. - Grab a minidump + cdb stack:
docs/guide/windows.md→ "Debugging children". - Verify the wrapper in use is
native/build/wrapclang/libcef_dll_wrapper.lib(non-bootstrap, per theCEF_USE_BOOTSTRAPnote).