NoMacSign in
← Blog

SSH into a cloud Mac from Windows or Linux

Start a macOS VM, sync your project, get a shell with Xcode on it, forward a port and pull the build back. A practical guide for WSL and Linux users.

· 7 min read

Need a Mac for this? NoMac gives your agent full macOS with Xcode, from $9.99 a month, billed by the second. Start now →


Most of what you need Xcode for is a command: xcodebuild, xcrun, simctl, swift test. If you are comfortable in a terminal, a remote desktop is mostly overhead. A shell on a Mac, with your project synced to it, is faster and far easier to script. This guide sets that up from Windows or Linux.

The shape of the workflow: edit locally in your own editor, sync to the Mac, run Apple tools over SSH, pull results back. Nothing about your local setup changes.

Prerequisites

Linux

Node 20 or newer, OpenSSH and rsync. Most distributions have the last two already.

# Debian or Ubuntu
sudo apt install openssh-client rsync
node --version   # 20 or newer

Windows

Use WSL. The sync and pull commands rely on rsync, which is simplest inside a Linux distribution. Keep the project inside the WSL filesystem (for example ~/code/MyApp) rather than under /mnt/c; file operations are much faster there. VS Code's WSL extension edits it transparently. See VS Code and WSL for iOS.

Install and log in

npm install -g @nomac/cli
nomac login

Approve the login in your browser. You need a NoMac plan with weekly hours; no Apple Developer account is needed for this guide.

Start a Mac and get a shell

cd ~/code/MyApp
nomac start --json      # ready in about a minute
nomac sync .            # upload the project
nomac ssh               # interactive shell on the Mac

You now have a macOS shell with root, Xcode and the command line tools. Check what you are working with:

xcodebuild -version
xcrun simctl list runtimes
sw_vers

Run single commands without a shell

For scripts and agents, run one command and return:

nomac ssh -- xcodebuild -list
nomac ssh -- xcodebuild -scheme MyApp \
  -destination 'generic/platform=iOS Simulator' build

Edit, sync, rebuild

Edit in your usual editor, then run nomac sync . again. It uploads changes, skips secret files and symlinks, and leaves extra remote files alone. That last point matters after a rename: the old file is still on the Mac. Delete it there explicitly, or Xcode may try to compile both.

Forward a port

If you run a local server on the Mac, for example a docs preview or a mock API your app talks to in the simulator, forward it to your machine:

nomac ssh --forward 8080:3000

Port 3000 on the Mac is now localhost:8080 on your machine for as long as the SSH connection is open.

Bring results back

nomac pull ./build --from build

Pull archives, test results, logs and screenshots before you stop. Use --overwrite only when you mean to replace local files.

Stop, and why a disconnect is not a stop

nomac stop --json

Closing your terminal or losing Wi-Fi does not stop the Mac, because long builds should survive a dropped connection. The idle timeout (ten minutes by default) and the session limit (two hours by default) eventually stop it, but billing runs until then. Make nomac stop a habit. Stopping deletes the VM and its files.

Tips for long work

  • ·Run long builds inside tmux on the Mac (brew install tmux if it is missing) so a dropped SSH connection does not kill them.
  • ·Script dependency setup (brew bundle, pod install, swift package resolve) so every fresh session reaches the same state.
  • ·If you need symlinks, use plain rsync or scp over the same SSH connection instead of nomac sync.
  • ·Check the session any time with nomac session status --json: state, usage and deadlines.

Want your agent to do all of this instead? See give Claude Code a Mac.

Give your agent a Mac in a minute.

Full macOS with Xcode and root, over MCP, CLI, API or SSH. Billed by the second, deleted when you stop. No Apple account needed to start.

Get started for $9.99

7-day money-back guarantee on your first purchase. Cancel anytime.

Connect your agent →