A SwiftUI desktop app that puts a polished GUI on top of Apple's container CLI — live resource charts, a ⌘K command palette, and full control over containers, images, volumes, and networks.
Apple shipped container — a tool for running Linux containers natively on Apple silicon, using a lightweight VM per container. It’s fast and it’s a great fit for the Mac, but it’s command-line only. I wanted the same at-a-glance overview I get from a desktop GUI, so I built one.
ContainerUI is a native SwiftUI app that drives Apple’s container tool. Run and inspect containers, manage images, volumes and networks, and control the system service — all from a polished Mac interface with live resource charts and a ⌘K command palette.
Why a GUI at all?h2
The container CLI is perfectly usable, but there’s a lot of context that a table of text hides. I wanted to see CPU and memory trending in real time, jump between a container and its logs without retyping IDs, and pull an image and run it in a couple of clicks. A GUI is the right shape for that kind of browsing.
The thin-seam approachh2
The most important design decision was not to bind to container’s internal Swift packages or its XPC apiserver. Those are only API-stable within patch versions and require matching entitlements. Instead, ContainerUI shells out to the documented CLI and decodes its --format json output.
That keeps the app decoupled and resilient — it stays compatible across container releases instead of breaking every time the internals shift. It’s the same approach mature Docker and Podman GUIs take, and it made the whole thing testable through one small seam:
SwiftUI Views ──▶ @Observable ViewModels ──▶ Services ──▶ ContainerCLI ──▶ CommandRunnerCommandRunner is just a protocol over process execution. In production a ProcessCommandRunner runs the real binary; in tests a MockCommandRunner feeds recorded CLI JSON fixtures. The unit tests are host-less — they compile the UI-independent Core/ sources and exercise JSON decoding, exact argv construction, and error classification with no live backend and no GUI launch.
What it doesh2
- Containers — list, inspect, start/stop/restart/kill, delete and prune, with live CPU/memory charts (real CPU % derived from counter deltas), streaming logs, exec, a full Run form, and a one-click console that opens an interactive shell in your terminal of choice.
- Images — pull with streaming progress, inspect config/env/layers/platforms, run a container straight from an image, tag, delete, prune.
- Volumes & Networks — create, inspect, delete and prune, with the built-in network protected.
- System — service status, versions, disk usage, reclaim-space pruning, and start/stop of the system service.
- ⌘K command palette — fuzzy search across every container, image, volume, network, and action.
The app auto-detects the container binary and shows a friendly state when the tool isn’t installed or the service isn’t running.
Install ith2
The easiest way is Homebrew:
brew install --cask kylemclaren/tap/container-uiThe owner/tap/name form auto-taps the tap, so it’s a single step, and the app updates itself in place from then on. You can also grab the DMG straight from the latest release.
You’ll need macOS 26 on Apple silicon — that’s a requirement of container itself — and Apple’s container tool installed.
Requirements and the road aheadh2
ContainerUI runs unsandboxed because it spawns /usr/local/bin/container, which talks to a launchd service over XPC that the App Sandbox blocks. It’s distributed with Developer ID and Hardened Runtime rather than through the Mac App Store.
There’s more to do — notarization is next on the list — but it’s already my daily driver for working with Apple’s containers.
Check it out on GitHub or read more at container-ui.fly.dev.