Skip to content

Repository files navigation

vessel

vessel — why run many commands when few keys do the trick?

A keyboard-driven terminal UI for Apple's native Mac containers (the OCI-compatible containers introduced in macOS at WWDC 2025). Live lists, logs, shells, images, and volumes - one screen, zero daemons, no CLI flags to memorize.

Star this repo Built for Apple container

CI Release License: MIT Go Platform Homebrew

InstallUsageKeybindingsConfigurationCLI matrixChangelogContributingLicense

Code of conductContributingLicenseSecurity

Demo

vessel demo

Keyboard-driven navigation across the containers, images, and volumes views, inspecting a container's detail pane, and starting/stopping a container with its status updating live in the list.

Full quality: docs/assets/demo.mp4

What it does

vessel gives you a keyboard-driven dashboard for managing Mac containers - the OCI-compatible native containers introduced in macOS at WWDC 2025. No more memorizing CLI flags or running multiple commands to see what's running.

  • Live container list with status, CPU %, memory, and sparklines
  • Start, stop, restart, remove, and prune
  • Drop into a shell inside any running container (clean UI restore on exit)
  • Run a one-shot command in a running container and see its output (e)
  • Stream logs with follow freeze and in-buffer search
  • Inspect containers: ports, mounts, networks and IP, CPUs, memory, platform, hostname, env, labels
  • Inspect images (digest, layers, command, platform variants) and volumes (quota, format, labels, options)
  • Browse / pull / prune images; tag, save, load, and push them; create / prune volumes
  • Filter on every list; multi-select; action menu; custom commands
  • Vim-style navigation, pane focus, mouse click/wheel

Requirements

  • macOS 26+ on Apple silicon (macOS 15 may work with limitations)
  • Apple Container CLI in your PATH
brew install container
container system start   # downloads a default Linux kernel on first run

Install

brew tap Laaaaksh/vessel
brew trust laaaaksh/vessel   # once; Homebrew 6+ refuses untrusted third-party taps
brew install vessel

On Homebrew versions before 6.0 there is no trust gate and no brew trust command - skip that step. See Tap Trust.

Or download a binary from GitHub Releases.

Usage

vessel
vessel doctor   # check CLI version, macOS, arch, system status, config

Keybindings

Key Action
h / l / / Move focus (sidebar / list / detail)
j / Move down
k / Move up
g / G Go to top / bottom
pgup / pgdown / ctrl+u / ctrl+d Page scroll
enter Open shell in container
e Run a one-shot command in the selected running container
L View logs
f Freeze / follow logs
s / u / r Stop / start / restart (stop asks to confirm when confirm_stop is set)
d Remove the marked row when one is marked, every marked row when 2+, else the selected row (confirm with y)
space Toggle multi-select mark (containers, images, volumes)
/ Filter current list
y Yank id / name / path
x Action menu
p Pull image (images view)
P Prune (stopped containers / images / volumes), confirm with y
c New container (form) / new volume (name prompt)
+ / _ Cycle layout
` Toggle command log
tab / 1-5 Containers / Images / Volumes / System / Networks
esc Close logs, help, modal, or clear filter
? Toggle help
q / ctrl+c Quit

A custom command with a key set fires on that key and replaces the built-in action on it, except on reserved keys (navigation, filtering, and the global keys) - config.example.toml documents which keys can be taken over. The in-app help (?) always lists what each key currently does.

Images: tag, save, load, push

Pick an image, press x, and choose Tag…, Save…, Load… or Push. Tag, save and push refuse two row shapes: an untagged row, whose bare repository would quietly resolve to a moving :latest, and a digest-pinned row (repo@sha256:…) - its reference is exact, but those verbs are not yet verified against pins. Save prompts for an archive path and confirms before overwriting a file that already exists; load prompts for an existing archive and says so plainly when the path is missing; push confirms first, because it publishes.

Known limits:

  • vessel never manages registry credentials. Push reuses whatever session container registry login has already established - running that login is yours to do.
  • Long-running verbs get real budgets: starting or stopping a container gets thirty seconds, image pull/tag/save/load/push, prunes and starting a container run up to two minutes, one batched delete of many targets gets one minute for the whole call, and a one-shot exec gets thirty seconds. A run without -d holds the action status until that budget expires instead of streaming output; streaming or detached-launch support for long-running foreground sessions is future work.

Configuration

vessel reads ~/.config/vessel/config.toml (see config.example.toml):

poll_interval = "2s"
log_tail_lines = 100
mouse_enabled = true
shell = "/bin/sh"

# [[custom_commands]]
# name = "inspect"
# key = "z"          # optional: "z", "space", "enter", "f5", "ctrl+z"
# command = "container inspect {{.ID}}"

Apple CLI matrix

Live probe notes for Apple container 1.2.x live in docs/APPLE_CONTAINER_MATRIX.md.

Changelog

Notable changes per release live in CHANGELOG.md.

Contributing

Contributions are welcome. See CONTRIBUTING.md.

Security

Found a security issue? Please report it privately - see SECURITY.md.

Star this repo

If vessel makes managing containers on your Mac easier, leave a star - it helps other people find it.

Star History Chart

License

MIT - see LICENSE.

About

A keyboard-driven TUI for Apple's native Mac containers

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages