Coding and operational rules for building, scripting, and automating virtual machines on macOS using Apple’s Virtualization framework, Parallels Desktop CLI, and VMware Fusion CLI.
Stop juggling complex VM configurations and manual provisioning scripts. These Cursor Rules turn macOS virtualization into a streamlined, automated development powerhouse using Apple's native Virtualization framework and enterprise tools.
You're building virtual environments for testing, CI/CD, or cross-platform development, but you're hitting these productivity killers:
These rules transform your virtualization workflow into a code-first, automation-friendly system that leverages Apple's native frameworks. You'll build robust VM provisioning with Swift 5.9, integrate seamlessly with Parallels Desktop and VMware Fusion CLIs, and create reproducible environments that scale from local development to CI pipelines.
Key Technical Advantages:
Before: Manual GUI-driven VM creation with trial-and-error resource allocation
# Manual process prone to errors
# 1. Open Parallels Desktop
# 2. Click through 12+ dialog screens
# 3. Manually configure CPU, RAM, storage
# 4. Download OS manually
# 5. Troubleshoot boot issues
After: One-command automated provisioning with validation
// Automated, validated, reproducible
let vmConfig = try VMConfigurationBuilder()
.withMacOSGuest(ipsw: .monterey)
.allocateResources(cores: .half, memory: .thirtyTwoGB)
.enableFileSharing(path: "./shared")
.build()
try await VMManager.provision(config: vmConfig)
Your VM configurations become version-controlled infrastructure code. No more "works on my machine" issues when team members or CI systems provision identical environments.
Automatic resource validation prevents overcommitment that crashes your host system during intensive development work.
You're building an iOS app that needs testing on macOS Monterey, Ventura, and Sonoma. Instead of maintaining three physical machines:
// Define your test matrix
let testConfigurations = [
VMConfig(os: .monterey, xcode: "14.3"),
VMConfig(os: .ventura, xcode: "15.1"),
VMConfig(os: .sonoma, xcode: "15.2")
]
// Provision all environments in parallel
try await withTaskGroup(of: VM.self) { group in
for config in testConfigurations {
group.addTask {
try await VMManager.provision(config)
}
}
}
Your testing pipeline now runs against all three environments simultaneously, cutting your validation time from hours to minutes.
Your GitHub Actions workflow needs clean macOS environments for each test run:
# .github/workflows/test.yml
- name: Provision Test VM
run: |
swift run VMProvisioner \
--template macos-13-xcode-15 \
--snapshot pre-test \
--resources cores=4,memory=16GB
- name: Run Tests in VM
run: |
prlctl exec test-vm "cd /shared && swift test"
- name: Cleanup
run: |
swift run VMManager --destroy test-vm
You're developing for both Intel and Apple Silicon, requiring different build environments:
enum Architecture {
case appleSilicon, intel
var optimalConfig: VMConfig {
switch self {
case .appleSilicon:
return VMConfig(
cores: .half,
memory: .sixteenGB,
virtualization: .native
)
case .intel:
return VMConfig(
cores: .quarter, // Intel VMs need less on Apple Silicon
memory: .eightGB,
virtualization: .rosetta
)
}
}
}
# Install required tools
brew install jq
# Ensure Xcode Command Line Tools
xcode-select --install
# Verify virtualization entitlements
codesign -d --entitlements - /Applications/YourApp.app
VMAutomation/
├── Sources/
│ ├── VMManager/
│ ├── Config/
│ └── Networking/
├── Resources/
│ ├── ipsw/
│ └── templates/
├── Scripts/
├── Tests/
└── Package.swift
Add these rules to your .cursorrules file and start building with:
import Virtualization
struct VMManager {
static func provision(_ config: VMConfig) async throws -> VM {
// Validate host requirements
guard Host.hasVirtualizationSupport else {
throw VMError.unsupportedHost
}
// Create VM with validation
let vm = try VZVirtualMachine(configuration: config.vzConfig)
try vm.validate()
return VM(vm: vm, config: config)
}
}
#!/usr/bin/env bash
set -euo pipefail
# Integrate with existing Parallels workflows
vm_create() {
local template="${1}"
local name="${2}"
prlctl create "${name}" --template "${template}"
prlctl set "${name}" --cpus "$(sysctl -n hw.ncpu | awk '{print int($1/2)}')"
prlctl snapshot "${name}" --name "clean-install"
}
Transform your macOS virtualization from a manual, error-prone process into a code-driven automation system. These rules eliminate the complexity while unlocking the full performance potential of Apple's virtualization ecosystem.
Your VMs become infrastructure code. Your provisioning becomes automated. Your development velocity accelerates.
You are an expert in: Swift 5.9, Apple Virtualization.framework, Bash/Zsh scripting, Parallels Desktop CLI (prlctl), VMware Fusion CLI (vmrun), Apple Silicon & Intel hardware.
Key Principles
- Prefer solutions that rely on Apple’s built-in Virtualization.framework; avoid 3rd-party kernel extensions (KEXTs).
- Target the host’s native CPU architecture (Apple Silicon → ARM64, Intel → x86_64). Do not emulate x86 on Apple Silicon unless absolutely required.
- Never over-commit resources: allocate ≤ 50 % of host RAM & CPU cores to any single VM.
- Store VM images on SSD/NVMe volumes; enable APFS snapshots for near-instant backups.
- Automate everything: VM build scripts, snapshot creation, and destruction should be idempotent and CI-friendly.
- Keep both host macOS and virtualization software patched to the latest stable releases.
Swift
- Use Swift 5.9 or newer.
- Prefer struct + protocol composition; avoid class inheritance except where required by VZ* APIs.
- Wrap every Virtualization API call in `try` blocks; propagate errors using `throws` or `Result`.
- Employ early-exit validation:
```swift
guard Host.isAppleSilicon else { throw VMError.unsupportedCPU }
```
- Use `async/await` for long-running operations (e.g., image downloads, VM install progress).
- Group code: `/Sources`, `/Resources/ipsw`, `/Scripts`, `/Tests`.
- Configuration constants belong in `.xcconfig` or `Config.swift` ‑ never hard-code paths.
Shell (Bash/Zsh)
- Start scripts with `#!/usr/bin/env bash` and `set -euo pipefail`.
- Quote every variable: `"${var}"`.
- Wrap CLI calls in functions that return non-zero on failure; trap ERR for unified cleanup.
- Use `jq` to parse JSON from `prlctl list --json` or `vmrun list -t json`.
Error Handling & Validation
- Validate host prerequisites at script launch:
• CPU architecture (sw_vers, sysctl).
• Available RAM & disk (`vm_stat`, `df -H`).
• Entitlements: `com.apple.vm.networking` & `com.apple.vm.graphics`.
- Abort early when requirements are not met; print actionable remediation steps.
- Catch and re-throw errors with context:
```swift
catch let error as VZError {
throw VMError.virtualizationFailed(reason: error.localizedDescription)
}
```
Apple Virtualization framework
- Always call `VZVirtualMachine.validate()` before starting a VM.
- macOS guests on Apple Silicon only: use `VZMacPlatformConfiguration` with `.ipsw` restoration image.
- Linux guests: prefer virtio devices (`VZVirtioBlockDeviceAttachment`, `VZVirtioNetworkDeviceConfiguration`).
- Use NAT networking (`VZNATNetworkDeviceAttachment`) by default; expose ports via `VZPortForwardingConfiguration`.
- Mount host folders via `VZSharedDirectory`: read-only for build artifacts, read-write for scratch space.
- Serial logging: attach `VZFileHandleSerialPortAttachment` to `/var/log/vm-${id}.log` for debugging.
Parallels Desktop CLI (prlctl)
- Use descriptive VM names: `<os>-<arch>-<purpose>-v<version>` (e.g., `win11-arm64-test-v1`).
- Always snapshot before risky operations: `prlctl snapshot "${VM}" --name pre-upgrade`.
- Convert `.ipsw` to a template once, then clone with `prlctl create VMName --template macOS-13`.
- Store configs in version control: `prlctl set "${VM}" --export-file config.yaml`.
VMware Fusion CLI (vmrun)
- Use `.vmx` templates stored under `Templates/`.
- Prefer `vmrun -T fusion` over GUI for CI jobs.
- Leverage `vmrun clone` with `linked` disks to save space.
Testing & CI
- In GitHub Actions, run headless VMs via `xcrun` + Virtualization.framework (`macos-12` runners only).
- Smoke-test guest network reachability (`ping`, `curl`) and toolchain versions after boot.
- Destroy disposable VMs after test completion to free resources.
Performance Optimisation
- Disable macOS guest animations: `defaults write -g NSAutomaticWindowAnimationsEnabled -bool false`.
- Reserve ≥ 20 GB free SSD space for swap spikes.
- Periodically trim APFS snapshots: `tmutil thinlocalsnapshots / 10000000000 4`.
Security & Compliance
- Use FileVault-encrypted APFS sparsebundles for sensitive VMs.
- Sign & notarize helper tools that request virtualization entitlements.
- No direct disk passthrough of USB mass storage containing production data.
Backup & Disaster Recovery
- Nightly `rsync --inplace --sparse` VM bundles to external storage.
- Keep at least 3 rotating snapshots (`daily`, `weekly`, `monthly`).
Documentation
- Each repo must contain `README.md > Setup`, `scripts/` usage docs, and a sample `config.json`.
- Change log every VM template bump: capture OS build number, framework version, and checksum.