Skip to main content
Devin now has access to macOS virtual machines. This means Devin can now build and test iOS and macOS applications.
If you’re on a Dedicated SaaS deployment, please reach out to your account team to enable macOS VMs.

How it works

macOS support is built on the same declarative configuration system as Linux. The runs-on field in your blueprint tells Devin which platform to build and run on, and each platform gets its own snapshot. The main differences from Linux are the shell, the file system layout, and the package manager:

Starting a macOS session

You can choose macOS per session:
  • Blueprint: add runs-on: macos so the repo’s snapshot is built for macOS (see below).
  • Slack: use the !mac bang command to start a session on a macOS VM.
  • API: set platform: "macos" when creating a session, schedule, or automation. See the API reference.

Writing macOS blueprints

Single-platform blueprint

If your repository only targets Apple platforms, use runs-on: macos at the top level:

Multi-platform blueprint

To build the same repository for more than one platform, write each platform as a separate YAML document separated by ---. Each document declares its own runs-on label. See the Multi-document YAML callout in the blueprint guide for background on this format.
Each document produces a separate snapshot build for its platform. Sessions boot from the platform-specific snapshot.
The top-level YAML must be a mapping, not a sequence. Writing the example above as a single list (- runs-on: default / - runs-on: macos) is rejected by the backend. Use the --- separator shown above.

The runs-on field

The runs-on field maps to a registered machine config on your account: You can specify runs-on as a string or a list:
The list syntax runs identical commands on every platform in the list. Only use it when commands are truly cross-platform (e.g. npm install). For platform-specific commands (like apt-get on Linux or brew on macOS), use the multi-document format instead.

Usage and cost

macOS sessions consume the same usage as equivalent Linux or Windows sessions. There is no macOS surcharge. For details on how usage is metered, see Usage.

What’s preinstalled

macOS session images ship with the Apple toolchain already installed, so your blueprint doesn’t have to download it: Versions move as Apple ships new releases and the image is refreshed. To see exactly what a session has, ask Devin to run:

Selecting an Xcode version

The default Xcode is the one xcode-select points at. To use another installed version for a single command, set DEVELOPER_DIR:
Use /usr/bin/xcodebuild (the shim that honors DEVELOPER_DIR) rather than a xcodebuild resolved from a specific Xcode’s Contents/Developer/usr/bin on PATH, which reports its own version regardless of DEVELOPER_DIR. Or switch the default for the whole session:
Put whichever you need in your blueprint so every session starts on the right toolchain.

macOS session behavior

Shell

macOS sessions use zsh as the default shell. Most POSIX shell commands work unchanged from Linux blueprints, but note the BSD userland: sed -i requires an argument (sed -i ''), and GNU tools like gsed, gdate, and greadlink come from the Homebrew coreutils formula.

Paths

Repositories are cloned to /Users/devin/repos/<repo-name>, and files you upload to a session are written to /Users/devin/.files/.

Secrets

Secrets are available as environment variables during sessions ($SECRET_NAME), same as on Linux. This is how to supply App Store Connect API keys, signing credentials, or private registry tokens:

Session sleep and wake

Sessions snapshot to disk when they sleep. Everything on disk survives a wake: installed tools, cloned repos, build caches, derived data. Running processes do not: dev servers, simulators, and watchers need to be restarted after the session wakes up.

Computer Use

Computer Use works on macOS sessions: Devin gets a full macOS desktop with Chrome, mouse, and keyboard, and can test macOS-native apps as well as web apps, and record what it does. Devin uses the Command key for macOS shortcuts (⌘C, ⌘V, ⌘Tab) rather than Control.

iOS Simulator

Devin can boot and drive the iOS Simulator directly:
The iOS Simulator tab in the session workspace streams the booted simulator, so you can watch Devin tap through your app in real time. It’s the Apple equivalent of Android emulator support.

Tips & Tricks

Warm build caches

A cold Xcode build results in a suboptimal developer experience, with longer build time. Use the maintenance field in environment.yml to prewarm the cache.
Resolved Swift packages, CocoaPods, and DerivedData will persist in the snapshot, so new sessions start from an incremental build.

Network access

Builds that fetch from CocoaPods, Swift Package Manager, Firebase, or a private registry need those hosts reachable. If your organization runs with a restricted network policy, make sure the macOS allowlist covers the same registries your Linux builds use. The two are configured separately, and a missing entry usually shows up as a dependency-resolution or TLS failure in the middle of a build.

Running containers

macOS VMs have no nested hardware virtualization, so a container runtime has to fall back to QEMU’s software emulation (TCG). Colima detects this and switches to emulation on its own:
The VM takes two to four minutes to become usable, and the first start can time out waiting for SSH while the emulated guest brings up networking, so retry the colima start if it fails. Containers then run roughly 15 to 25x slower on CPU than native, with a few seconds of startup each; pulls run at host network speed. That’s fine for a linting or packaging container, painful for compiling. For container-heavy work, use a Linux session or point the macOS session at a remote Docker daemon.

Don’t install Xcode in a blueprint unless you have to

Xcode is a multi-gigabyte download, and Apple gates it behind an Apple ID. Prefer the versions already in the image, selected with DEVELOPER_DIR or xcode-select. If you need a different release or beta, you can store an Apple ID as a secret and have the blueprint download that version, at the cost of a much slower build.

Limitations

Troubleshooting

Builds are much slower in the first session after a snapshot rebuild. DerivedData was rebuilt from scratch. Add a build-for-testing step to maintenance so the snapshot carries a warm build. xcodebuild picks the wrong toolchain. Check xcode-select -p, and set DEVELOPER_DIR explicitly in the blueprint step. A destination isn’t found. Run xcrun simctl list devices available to see what the installed runtimes actually provide, and match the -destination name and OS to it. Dependency resolution hangs or fails with a TLS error. The host is likely missing from your organization’s network allowlist for macOS. See Network access.