Industry Commentary

Apple's Container Runtime and the Mac Dev Stack Question

By John Jansen · · 6 min read

Share

Apple's container project drifting into the GitHub daily top five wasn't a surprise to anyone who has spent a Monday morning watching Docker Desktop chew through battery before the first build. It is, however, the first time in a while that Mac dev teams have had a genuinely first-party answer to a question they've been working around for years: why is the container runtime on the most popular developer laptop in the world a third-party product running a Linux VM that pretends the host doesn't exist?

The short version of Apple's move: each container gets its own lightweight VM, built on the Virtualization framework, with an Apple Silicon–native image format and an OCI-compatible path for everything else. No shared daemon. No Docker socket as a single point of contention. Sub-second start times in the demos, and — more importantly — a runtime that treats arm64 as the first-class target rather than the awkward cousin.

That's worth taking seriously. It's also worth being honest about what it changes and what it doesn't.

What actually shifts

The interesting architectural decision is one VM per container. Docker Desktop and OrbStack both run a single Linux VM and multiplex containers inside it. That model is efficient on memory but it's also why a misbehaving container can drag the whole runtime down, why filesystem sharing has been a recurring source of pain, and why networking has always required a small dictionary of workarounds.

Apple's per-container VM model trades some of that efficiency for isolation that lines up with how the rest of macOS thinks about processes. The cost is real — each VM has overhead — but on machines with 32GB or 64GB of unified memory, the budget is there. For teams running three or four services locally, this is a reasonable trade. For teams spinning up twenty containers to mirror production, it's not, at least not yet.

The Apple Silicon–native image story matters more than the runtime story in the long run. If you've shipped a Node or Python service to a Graviton instance or an arm64 Kubernetes node, you already know the linker errors, the base image substitutions, the --platform linux/amd64 escape hatches that quietly slow down every build on a developer laptop. A runtime that assumes arm64 by default, and treats x86 images as the thing requiring emulation, inverts the friction. That's the right direction.

Where it earns its place today

We've been running it on internal work for a few weeks. Our position, which we'll keep updating:

Use it for: single-service development loops, language runtimes with native arm64 images (Go, Rust, Node, Python, JVM), anything where you want fast cold starts and you don't care about Compose-style orchestration. The cold start times are not marketing — they're real, and they change how you think about scratch containers for one-off tasks. We've started using it for ephemeral database instances during integration test development where previously we'd have left a long-running Postgres container around because the startup cost wasn't worth it.

Use it for: CI parity experiments where the CI target is arm64. If your production runs on Graviton or arm64 nodes, building and testing on a runtime that doesn't lie to you about the architecture is a meaningful win. The bugs you find on the laptop are the bugs you'd find in production.

Keep on Docker Desktop or OrbStack: multi-service Compose stacks, anything depending on the Docker socket directly (Testcontainers being the obvious one, though that's evolving), Kubernetes-in-Docker setups, and workloads where you've built tooling around docker exec and the assumption of a long-running daemon. The ecosystem assumption that there is a Docker daemon is deeply embedded, and Apple's runtime doesn't try to pretend otherwise.

Don't use it yet for: anything where you need predictable behaviour across a team with mixed Intel Macs and Apple Silicon Macs. The runtime is Apple Silicon only, and your build matrix has to account for that. If half your team is still on Intel hardware, you're introducing a fork in the local dev experience that isn't worth the gain.

The portability cost

This is where engineering leaders need a position. Apple's runtime is OCI-compatible at the image level, which means images built with it run elsewhere and images from elsewhere run on it. That's the portability floor, and it's solid.

The portability ceiling is lower. Anything that depends on the Docker CLI's specific behaviour, the Docker socket, Compose semantics, or BuildKit features beyond the basics will need adapters or rewrites. Apple ships a CLI that covers the common cases, but it's not a drop-in for docker and shouldn't be treated as one. Teams that have standardised their local dev experience around docker compose up are not going to migrate by editing a shell alias.

The quieter portability question is about Linux. macOS-native containers are still Linux containers — the VM is doing the Linux part — so the runtime doesn't change what runs inside. What it changes is the local developer's relationship to that Linux environment. The shared-filesystem model goes away. Networking gets cleaner but different. If your onboarding docs say "mount your source directory and edit live," those docs need rewriting.

Our view: the portability cost is acceptable if you treat the Apple runtime as one of several local options rather than a replacement. Teams that have already invested in reproducible dev environments — devcontainers, Nix, a sensible Makefile — absorb the change cheaply. Teams whose local setup is a pile of docker run commands accumulated over four years will feel it more.

What this means for the daemon-based incumbents

Docker Desktop's commercial position isn't threatened by this in the short term. The licensing model, the GUI, the Kubernetes integration, the enterprise features — none of that is what Apple is competing on. OrbStack is in a more interesting spot because its pitch has always been "the Docker experience, but fast and native on Apple Silicon." Apple just made native a first-party feature.

What we'd expect: OrbStack leans harder into the polish, the Compose support, and the things Apple won't prioritise — better UX around volumes, sensible defaults for cross-platform builds, the Kubernetes story. Docker doubles down on the cross-platform consistency story and on Build Cloud. Both are reasonable responses. Neither makes Apple's runtime less interesting for the workloads it's actually good at.

A position to take

If we were advising a Mac-heavy engineering org today, the recommendation would be: pilot Apple's runtime for new services where the team controls the local dev story end-to-end. Keep the existing daemon-based runtime for everything else. Don't migrate Compose stacks. Don't rewrite tooling. Watch the Testcontainers and BuildKit integration stories closely, because those determine whether this becomes a credible default in 18 months or stays a fast-path tool for specific workloads.

The real win isn't replacing Docker Desktop. It's that the Mac is no longer a second-class container host. For a platform that ships on most engineering laptops, that should have happened years ago. That it's happening now, with an architecture that takes Apple Silicon seriously rather than treating it as a porting target, is the part worth paying attention to.

Want to discuss this?

We write about what we're actually working on. If this is relevant to something you're building, we'd love to hear about it.