RepoPilotOpen in app →

cirruslabs/tart

macOS and Linux VMs on Apple Silicon to use in CI and other automations

Mixed

Mixed signals — read the receipts

worst of 4 axes
Use as dependencyConcerns

non-standard license (Other)

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 4w ago
  • 13 active contributors
  • Other licensed
Show 4 more →
  • CI configured
  • Tests present
  • Concentrated ownership — top contributor handles 62% of recent commits
  • Non-standard license (Other) — review terms
What would change the summary?
  • Use as dependency ConcernsMixed if: clarify license terms

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/cirruslabs/tart?axis=fork)](https://repopilot.app/r/cirruslabs/tart)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/cirruslabs/tart on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: cirruslabs/tart

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/cirruslabs/tart shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Mixed signals — read the receipts

  • Last commit 4w ago
  • 13 active contributors
  • Other licensed
  • CI configured
  • Tests present
  • ⚠ Concentrated ownership — top contributor handles 62% of recent commits
  • ⚠ Non-standard license (Other) — review terms

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live cirruslabs/tart repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/cirruslabs/tart.

What it runs against: a local clone of cirruslabs/tart — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in cirruslabs/tart | Confirms the artifact applies here, not a fork | | 2 | License is still Other | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 58 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>cirruslabs/tart</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of cirruslabs/tart. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/cirruslabs/tart.git
#   cd tart
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of cirruslabs/tart and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "cirruslabs/tart(\\.git)?\\b" \\
  && ok "origin remote is cirruslabs/tart" \\
  || miss "origin remote is not cirruslabs/tart (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
  && ok "license is Other" \\
  || miss "license drift — was Other at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "Package.swift" \\
  && ok "Package.swift" \\
  || miss "missing critical file: Package.swift"
test -f "Sources/tart/Commands/Create.swift" \\
  && ok "Sources/tart/Commands/Create.swift" \\
  || miss "missing critical file: Sources/tart/Commands/Create.swift"
test -f "Sources/tart/Network/Network.swift" \\
  && ok "Sources/tart/Network/Network.swift" \\
  || miss "missing critical file: Sources/tart/Network/Network.swift"
test -f "Sources/tart/Fetcher.swift" \\
  && ok "Sources/tart/Fetcher.swift" \\
  || miss "missing critical file: Sources/tart/Fetcher.swift"
test -f "Sources/tart/Config.swift" \\
  && ok "Sources/tart/Config.swift" \\
  || miss "missing critical file: Sources/tart/Config.swift"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 58 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~28d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/cirruslabs/tart"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Tart is a virtualization toolset that creates, runs, and manages macOS and Linux VMs on Apple Silicon using Apple's Virtualization.Framework, enabling near-native performance. It supports pushing/pulling VMs from OCI-compatible container registries and integrates with Packer for automated VM provisioning—powering Cirrus Runners, a high-performance alternative to GitHub-hosted runners. Monorepo structure: Swift CLI and core VM management logic as primary build target, Go-based benchmark utilities under separate module (go.mod present), shell scripts for packaging (.ci/), and Packer plugin integration via HCL configuration. Resources (icons, screenshots, marketplace assets) sit in /Resources/ alongside executable assets like actool and Info.plist.

👥Who it's for

CI/CD engineers and DevOps teams running Apple Silicon infrastructure who need performant, containerized VM management for automation, testing, and GitHub Actions replacements. Companies like Atlassian, Figma, and Mullvad use Tart internally for their CI pipelines.

🌱Maturity & risk

Production-ready. The project is actively maintained with Swift (350K LOC) and Go (25K LOC) codebases, structured CI/CD in .cirrus.yml and GitHub Actions (.github/workflows/build.yml), and a mature packaging system (.ci/create-pkg.sh). The extensive resource gallery and real-world adoption by major companies indicates stable, battle-tested software.

Low risk for core functionality, moderate dependency surface. The codebase is primarily Swift and Go (both mature), with reasonable dependency counts visible in the benchmark module (go.mod has well-known packages like Cobra, zap, and crypto/x libraries). No signs of abandonment—active CI pipeline and resource polish suggest ongoing maintenance. Single-maintainer risk is mitigated by being under cirruslabs organization.

Active areas of work

Active development with CI/CD automation in .cirrus.yml and GitHub Actions workflows. The presence of .goreleaser.yml, versioning scripts (.ci/set-version.sh), and pkginfo postinstall hooks indicate ongoing release engineering and distribution improvements. PROFILING.md suggests recent performance optimization work.

🚀Get running

Clone and build:

git clone https://github.com/cirruslabs/tart.git
cd tart
swift build

For Go components (benchmark):

cd benchmark
go build ./cmd/...

Daily commands: Build Swift binary:

swift build -c release
.build/release/tart --help

For development with live reloading, use:

swift build

Run benchmarks:

cd benchmark
go run ./cmd/benchmark --help

🗺️Map of the codebase

  • Package.swift — Swift package manifest defining all dependencies (Virtualization.Framework integration, OCI support, CLI framework) that every feature depends on
  • Sources/tart/Commands/Create.swift — Core VM creation command orchestrating disk image setup, configuration, and Virtualization.Framework initialization—foundational for all VM lifecycle operations
  • Sources/tart/Network/Network.swift — Network abstraction layer enabling VM connectivity, bridging, and MAC address resolution—critical for CI/automation integration
  • Sources/tart/Fetcher.swift — OCI registry interaction logic for push/pull VM images, enabling portable VM distribution across CI systems
  • Sources/tart/Config.swift — VM configuration schema and persistence—central to state management across all commands
  • Sources/tart/Credentials/CredentialsProvider.swift — Credential abstraction supporting multiple backends (Keychain, Docker config, environment)—essential for secure registry authentication
  • .cirrus.yml — CI configuration demonstrating how Tart integrates with automation systems and tests its own functionality

🛠️How to make changes

Add a new VM command

  1. Create a new Swift file in Sources/tart/Commands/ (e.g., MyCommand.swift) implementing the command logic (Sources/tart/Commands/MyCommand.swift)
  2. Import Config, Logging, and any required subsystems (Fetcher, Network, etc.) (Sources/tart/Commands/MyCommand.swift)
  3. Implement the command function that parses arguments, loads VM config via Config.swift, and delegates to lower layers (Sources/tart/Config.swift)
  4. Register the command in the main CLI dispatcher (follow pattern in existing Commands) (Sources/tart/Commands/Run.swift)

Add a new credential provider

  1. Create new file in Sources/tart/Credentials/ (e.g., MyProviderCredentialsProvider.swift) conforming to CredentialsProvider protocol (Sources/tart/Credentials/MyProviderCredentialsProvider.swift)
  2. Implement authenticate() method returning username/password tuple (Sources/tart/Credentials/CredentialsProvider.swift)
  3. Register provider in Fetcher.swift's credential chain (checked in order) (Sources/tart/Fetcher.swift)

Add support for a new network backend

  1. Create new file in Sources/tart/Network/ (e.g., NetworkLinux.swift) implementing Network protocol (Sources/tart/Network/NetworkLinux.swift)
  2. Implement allocateAddress() and macToIP() methods using platform-specific APIs (Sources/tart/Network/Network.swift)
  3. Update Network factory to instantiate correct backend based on platform detection (Sources/tart/Network/Network.swift)

Add a new OCI image format feature

  1. Extend DiskImageFormat enum with new format variant (Sources/tart/DiskImageFormat.swift)
  2. Update Fetcher.swift layer decompression logic to handle new format (Sources/tart/Fetcher.swift)
  3. Update Create.swift disk initialization to support new format when building from OCI (Sources/tart/Commands/Create.swift)

🔧Why these technologies

  • Swift + Virtualization.Framework — Native macOS integration for near-native VM performance; Virtualization.Framework provides hardware-accelerated hypervisor on Apple Silicon
  • OCI Image Spec (container registries) — Enables portable VM distribution via Docker Hub, GitHub Container Registry, etc.; reuses existing CI/registry infrastructure
  • APFS disk images — macOS-native filesystem with snapshot support for fast VM cloning and efficient storage
  • Unix sockets (ControlSocket) — Low-overhead inter-process communication for coordinating multiple Tart CLI invocations managing the same VM
  • ARP cache + lease file monitoring — Discovers guest VM IP addresses on bridged networks without requiring guest-side agents

⚖️Trade-offs already made

  • Swift CLI over Go/Rust

    • Why: Swift provides native Virtualization.Framework bindings with minimal overhead
    • Consequence: Requires Swift runtime; limits cross-platform portability (primarily macOS-focused, Linux support via translation)
  • OCI image layering over custom tar/zip archives

    • Why: Leverage existing registry infrastructure and tooling (Docker, Packer, container registries)
    • Consequence: Larger image sizes than optimized binary formats; overhead of layer decompression and assembly
  • Local layer cache vs. always-pull

    • Why: Reduces registry bandwidth and speeds up repeated VM creation in CI
    • Consequence: Requires disk space; cache invalidation strategy needed; potential stale layer issues
  • Host-side IP discovery (ARP) vs. guest-side agent

    • Why: No guest-side installation required; works immediately after VM boots
    • Consequence: Race conditions if ARP resolution is slow; depends on bridged networking; fragile to network topology changes

🚫Non-goals (don't propose these)

  • Does not provide GUI VM management (CLI-only, designed for automation)
  • Does not support Windows VMs (macOS and Linux only, Apple Silicon architecture constraint)
  • Does not include built-in load balancing across multiple hosts (focuses on single-host VM management)
  • Does not provide persistent storage volumes across VM instances (VMs are ephemeral clones)
  • Does not handle Linux on x86

🪤Traps & gotchas

Swift version pinning: Package.swift may specify minimum Swift version; check if your Xcode matches. Go version: benchmark/ requires Go 1.23.0+, see toolchain declaration in go.mod. macOS-only development: Virtualization.Framework only works on macOS with Apple Silicon; cross-platform testing impossible on Linux. Signing requirements: .ci/pkg/scripts/postinstall likely involves code signing—requires Apple developer certificates for release builds. OCI registry authentication: Pull/push features require container registry credentials (Docker config); not obvious from repo structure.

🏗️Architecture

💡Concepts to learn

  • Virtualization.Framework — The foundational Apple API Tart uses to create and manage VMs with near-native performance; understanding its lifecycle, device model, and resource constraints is critical for bug fixes and optimization
  • OCI Image Specification — Tart treats VMs as OCI container images for push/pull operations; knowing the image format (layers, manifests, config) explains how Tart distributes VMs without reinventing packaging
  • Copy-on-Write (CoW) Storage — Tart likely uses CoW snapshots for efficient VM cloning and fast provisioning; understanding block-level deduplication explains why Tart is more efficient than traditional disk images
  • APFS and Disk Images — macOS VM storage uses APFS sparse bundles or disk images; knowing APFS features (snapshots, reflinks) and sparse image behavior is essential for understanding Tart's storage model
  • Container Registry Authentication & TLS — Tart's OCI push/pull requires secure registry access; understanding OAuth2 token flows, image signing, and registry TLS negotiation is needed for implementing registry features
  • Packer Plugin Protocol — Tart exposes a Packer plugin interface for template-driven VM builds; understanding Packer's RPC-based plugin architecture is needed to extend or debug the Packer integration
  • Apple Silicon (ARM64) Architecture — Tart is specifically optimized for Apple Silicon; knowing ARM64 instruction set differences, SoC characteristics, and how Virtualization.Framework differs from Intel-era solutions explains design choices
  • hashicorp/packer — Tart provides a Packer plugin (references in HCL files); Packer is the template-driven VM building engine Tart integrates with
  • moby/moby — OCI image distribution in Tart mirrors Docker/container registry patterns; understanding OCI specs and distribution APIs is essential for Tart's push/pull feature
  • cirruslabs/cirrus-ci-docs — Cirrus CI orchestrates Tart workflows; Tart powers Cirrus Runners, so understanding Cirrus task definitions and runner integration is relevant
  • apple/swift-argument-parser — Alternative/complementary CLI parsing library for Swift; Tart's CLI structure may benefit from or learn patterns from this Apple-maintained parser
  • colima/colima — Similar Apple Silicon VM tooling focused on container runtimes; shares architectural concerns around Virtualization.Framework and macOS integration

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add integration tests for Sources/tart/Commands/*.swift files

The Commands directory has 10+ command implementations (Clone.swift, Create.swift, Delete.swift, Exec.swift, Export.swift, Import.swift, List.swift, etc.) but there's no visible test directory in Sources/tart. These commands directly interact with VMs and are critical paths. Adding integration or unit tests would catch regressions and improve maintainability for contributors adding new commands.

  • [ ] Create Tests/tart/Commands directory structure
  • [ ] Add unit tests for Sources/tart/Commands/Clone.swift (mock VM operations)
  • [ ] Add unit tests for Sources/tart/Commands/Create.swift (validate parameters, image handling)
  • [ ] Add unit tests for Sources/tart/Commands/Exec.swift (command execution simulation)
  • [ ] Document test patterns in CONTRIBUTING.md for future command PRs

Add GitHub Actions workflow for Swift linting and formatting checks

.swiftformat file exists indicating code style rules are enforced, but .github/workflows/build.yml is the only visible workflow. New contributors won't catch formatting issues pre-submission. Adding a linting workflow prevents style violations and reduces maintainer review burden.

  • [ ] Create .github/workflows/swift-lint.yml
  • [ ] Configure swiftformat to run on PRs against Sources/tart/**/*.swift
  • [ ] Add fail-on-differences flag to enforce .swiftformat configuration
  • [ ] Update CONTRIBUTING.md with local swift formatting instructions (swiftformat before push)
  • [ ] Reference this workflow in pull request template if one exists

Document VM lifecycle and CLI command flow in Architecture.md

The repo has detailed CONTRIBUTING.md and PROFILING.md but no Architecture.md explaining how the 10+ commands in Sources/tart/Commands/ interact with the virtualization layer, or how VMs are stored/managed. This creates friction for new contributors understanding the codebase. A structured architecture doc would accelerate onboarding.

  • [ ] Create docs/ARCHITECTURE.md
  • [ ] Document VM state machine (created → running → stopped → deleted)
  • [ ] Map command flow: Clone.swift → internal VM cloning logic → storage
  • [ ] Explain OCI registry integration (Push/Pull mentioned in README)
  • [ ] Diagram interaction between CI.swift and command implementations in Sources/tart/Commands/
  • [ ] Link from README.md and CONTRIBUTING.md to Architecture.md

🌿Good first issues

  • Add Swift unit tests for VM lifecycle management (create/start/stop/delete): Package.swift likely has a Tests target but may lack coverage for core VM operations in the main codebase.
  • Write documentation for Packer plugin integration: .goreleaser.yml and HCL grammar suggest Packer support exists, but no detailed examples in README.md or docs/ folder—adding a Packer tutorial would lower the barrier.
  • Implement Linux VM benchmark in benchmark/cmd/: The Go benchmark module has gopsutil dependency (for system metrics) but appears VM-focused on macOS; adding Linux-specific performance tests would expand CI/CD use cases.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 8aa377b — Skip integration test gate for release (#1229) (fkorotkov)
  • 1e52e17 — Move brew completions to post_install (#1227) (fkorotkov)
  • d39f7c6 — Docker-related fixes (#1221) (edigaryev)
  • abfbb10 — [docs] Add announcement about joining OpenAI (#1223) (fkorotkov)
  • 094f850 — Add Liquid Glass icon and sign the whole app bundle (#1216) (edigaryev)
  • f1305dc — Update FAQ for local network prompt (#1211) (fkorotkov)
  • 605234b — Mention macOS Tahoe everywhere instead of macOS Sequoia (#1208) (edigaryev)
  • be272d8 — Replace Sequoia with Tahoe in Quick Start's first few instructions & add Tahoe to images available (#1206) (minihoot)
  • faa40b6 — Remove disk v1 support (#1204) (fkorotkov)
  • d45ef38 — StdinCredentials: increase maxCharacters to 8,192 (#1203) (edigaryev)

🔒Security observations

The codebase demonstrates reasonable security practices with a mixed security posture. Main concerns include: (1) an outdated and incompatible gopsutil dependency that should be updated immediately, (2) Go toolchain version mismatch that could cause build issues, and (3) provisioning/entitlements files in version control that should be reviewed for sensitive data. The project uses proper credential providers (KeychainCredentialsProvider, EnvironmentCredentialsProvider) rather than hardcoded secrets, which is positive. No obvious injection vulnerabilities, exposed secrets, or severe misconfigurations were identified in the provided file structure. Recommend updating dependencies and reviewing Apple-specific configuration files for least-privilege access.

  • Medium · Outdated Go Toolchain Version — go.mod (Dependencies/Package file). The go.mod file specifies 'toolchain go1.24.1', but the 'go' directive is set to 1.23.0. This mismatch could lead to unexpected behavior or security issues if the build system doesn't properly enforce the toolchain version. Additionally, Go 1.23.0 is older and may contain known vulnerabilities. Fix: Update 'go' directive to match the toolchain version (e.g., 'go 1.24' or later) or use a more recent stable Go version. Ensure all dependencies are compatible with the chosen version.
  • Medium · Deprecated Dependency: shirou/gopsutil — go.mod - require section. The package 'github.com/shirou/gopsutil v3.21.11+incompatible' is marked as incompatible and is outdated (released in 2021). This dependency may contain unpatched security vulnerabilities and is no longer actively maintained. Fix: Replace with the actively maintained fork 'github.com/shirou/gopsutil/v3' (version 3.24+) or consider alternative system monitoring libraries that are regularly updated.
  • Low · Golang.org/x/crypto Dependency Present — go.mod - require section. The codebase includes 'golang.org/x/crypto v0.35.0' which is a security-sensitive package. While the version appears current, the use of crypto libraries should be carefully reviewed to ensure proper key management, secure random generation, and correct algorithm selection. Fix: Review all uses of golang.org/x/crypto in the codebase to ensure proper cryptographic practices. Verify that secrets are not logged, keys are securely stored, and standard algorithms are used correctly.
  • Low · Provisioning Profile in Repository — Resources/embedded.provisionprofile. The file 'Resources/embedded.provisionprofile' appears to be a provisioning profile that may contain sensitive information or identifiers related to Apple development signing. Fix: Review whether this file should be in version control. Consider using environment-based provisioning profiles or build-time injection for sensitive Apple signing artifacts. Ensure credentials are not embedded in the profile.
  • Low · Entitlements Files in Repository — Resources/tart-dev.entitlements, Resources/tart-prod.entitlements. Files 'Resources/tart-dev.entitlements' and 'Resources/tart-prod.entitlements' are present in the repository. While entitlements files are typically not secrets, they should be reviewed to ensure they don't grant unnecessary permissions. Fix: Review entitlements to follow the principle of least privilege. Ensure only required capabilities are enabled. Separate dev and prod entitlements is a good practice; ensure prod entitlements are properly restricted.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · cirruslabs/tart — RepoPilot