Native Swift CLI that reads devcontainer.json and runs development environments on Apple container.
Use up with an existing checkout, or use clone to keep the repository in a named volume for faster I/O. Work from your terminal, an AI agent or VS Code.
For implementation details and behavior beyond this quick reference, see the technical documentation.
- macOS 26+ on Apple Silicon
- Apple
container, installed separately
brew install wcgomes/tap/adevcontainer
sudo adevcontainer plugin --installRun sudo adevcontainer plugin --install once after install, and again only after upgrading Apple container. brew upgrade adevcontainer does not require plugin --install again when the plugin symlink already targets $(brew --prefix)/opt/adevcontainer/bin/adevcontainer.
Download adevcontainer-macos-arm64.tar.gz and adevcontainer-macos-arm64.tar.gz.sha256 from GitHub Releases, then run:
shasum -a 256 -c adevcontainer-macos-arm64.tar.gz.sha256
tar xzf adevcontainer-macos-arm64.tar.gz
sudo mv adevcontainer /usr/local/bin/ # or move it to another directory on PATH
sudo adevcontainer plugin --install # sudo when the plugin destination requires elevationVerify the installation and Apple container setup:
adevcontainer doctorTo build from source, follow CONTRIBUTING.md.
Your project must contain .devcontainer/devcontainer.json or .devcontainer.json.
From the project directory:
adevcontainer up
adevcontainer execTip: Apple Containers works differently from other container runtimes: it uses a lightweight VM per container instead of sharing one super VM, but its default resources can be low or insufficient for dev containers; if a container is unresponsive, consider setting
hostRequirementsindevcontainer.json.
To use another local directory, run adevcontainer up -w <path>.
You do not need a local checkout. Use an HTTPS or SSH Git URL:
adevcontainer clone https://github.com/org/repo.git
adevcontainer execThe cloned source remains in a named volume. You can work, commit, and push from inside the container.
If bring-up fails after the config-only fetch, the CLI retains that checkout for recovery. On a
TTY it offers to open and retry the config; in automation, edit the printed path and run the exact
adevcontainer clone <git-url> --resume <config-dir> command.
After adevcontainer plugin --install, every command also works as container dev <subcommand>. PATH adevcontainer remains valid. plugin --uninstall removes only the plugin bin/dev link and config.toml.
Apple must be running to dispatch plugins:
container system startExamples:
container dev up
container dev exec
container dev list
container dev doctorApple upgrades wipe the plugin directory. PATH adevcontainer survives. Restage with PATH adevcontainer plugin --install (sudo when the destination requires elevation), again only after upgrading Apple container. brew upgrade adevcontainer does not require restage when the symlink already targets the Homebrew opt path.
The start, exec, stop, delete, purge, rebuild, and inspect commands open an interactive picker (picklist) in an interactive TTY when --name is not provided and multiple managed containers exist. In a non-interactive terminal, --name <name> is required in this case.
| Command | Purpose |
|---|---|
adevcontainer doctor |
Check Apple container readiness |
adevcontainer plugin --install |
Link the Apple CLI plugin (bin/dev absolute symlink and config.toml) |
adevcontainer plugin --uninstall |
Remove plugin bin/dev and config.toml only |
adevcontainer up [-w <path>] [--vscode] |
Create or start a dev container from a local folder |
adevcontainer clone <git-url> [--vscode] [--resume <config-dir>] |
Clone a repository into a named volume and start its dev container |
adevcontainer exec [-it] [--name <name>] [--] [cmd…] |
Open a shell or run a command in a running managed container |
adevcontainer list [--json] |
List managed dev containers |
adevcontainer start [--name <name>] [--vscode] [--json] |
Start a managed container; prepare or repair automatic Git credentials, including running reuse |
adevcontainer stop [--name <name>] |
Stop a container by name or with the interactive picker |
adevcontainer inspect [--name <name>] |
Inspect a container by name or with the interactive picker |
adevcontainer delete [--name <name>] |
Remove a container, keeping its managed volumes |
adevcontainer purge [--name <name>] |
Remove a container, its managed volumes, and the image |
adevcontainer rebuild [--name <name>] [--vscode] |
Rebuild a managed container from its current configuration |
adevcontainer help [<command>] |
Show main usage or per-command help |
adevcontainer version [--version] |
Print the CLI version |
Use your existing host Git login for HTTP(S) repositories inside your dev
container, without a separate container login. Setup is automatic during up,
clone, start, and rebuild, before the in-container clone or lifecycle hooks.
Keep your host login valid. If authentication stops working, sign in again on
the host and run adevcontainer up or adevcontainer start to repair the
connection—even when the container is already running.
For local SSH Git remotes, fresh up and bind-mode rebuild automatically forward
your host SSH agent when SSH_AUTH_SOCK points to a socket; HTTPS-only workspaces
do not automatically expose it. If forwarding is unavailable in an existing
container, run adevcontainer rebuild --name <name> to apply create-time settings.
See the Git credential implementation notes for technical details and troubleshooting.
On macOS 26+ Apple Silicon with Swift/CLT, curl, tar/xz and SHA-256 tools:
sh scripts/build-guest-credential-relay.sh
swift build -c release --product adevcontainerPreparation downloads only the official checksum-pinned Zig 0.15.2 toolchain into
.build/toolchains/zig-0.15.2/ (initial HTTPS access to ziglang.org is required).
Every use verifies the archive and extracts a fresh private compiler/sysroot;
installed Zig is not consulted. Both static linux/arm64 and linux/amd64 helpers
are verified and embedded in generated, gitignored Swift source. Build outputs
and toolchains are not runtime dependencies. Source/CI builds must prepare these
assets first; releases remain one relocatable CLI plus license notices.
When up or clone cannot bring up a container after an editable devcontainer.json exists,
interactive TTY mode prints the structured failure, asks Open the recovery editor now? [Y/n],
and retries the complete create path after a valid edit. Declining or EOF returns the original
failure. Non-TTY and --json never prompt or edit; up prints a host-config retry hint, while
clone retains its config checkout and prints an exact clone --resume command.
If start cannot start a selected managed container, TTY recovery asks the same question and
delegates to rebuild --name <name>; it never re-runs start or opens an editor. Non-TTY,
--json, decline, and EOF return the original start failure with the rebuild hint.
up, clone, and rebuild apply supported customizations.vscode.settings and customizations.vscode.extensions from devcontainer.json by default (soft-fail; not full Dev Containers extension parity). start does not apply settings or extensions.
--vscode only opens a new VS Code window on the remote workspace and gates postAttachCommand. Install the Remote - Containers extension and make sure the code CLI is available:
adevcontainer up --vscodeSee CONTRIBUTING.md for prerequisites, source builds, tests, fixtures, and the repository development workflow.
Technical design and project decisions are documented in the wiki.
This project is available under the MIT License.

