This is the multi-page printable view of this section. Click here to print.
Plug-in
1 - VM driver plugins
2 - CLI plugins
Warning Support for CLI plugins is experimental
| ⚡ Requirement | Lima >= 2.0 |
|---|
Lima supports a plugin-like command aliasing system similar to git, kubectl, and docker. When you run a limactl command that doesn’t exist, Lima will automatically look for an external program named limactl-<command> in your system’s PATH and additional directories.
Plugin Discovery
Lima discovers plugins by scanning for executables named limactl-<plugin-name> in the following locations:
- Directory containing the
limactlbinary (including symlink support) - All directories in your
$PATHenvironment variable <PREFIX>/libexec/lima- For plugins installed by package managers or distribution packages
Plugin discovery respects symlinks, ensuring that even if limactl is installed via Homebrew and points to a symlink, all plugins are correctly discovered.
Plugin Information
Available plugins are automatically displayed in:
limactl --help- Shows all discovered plugins with descriptions in an “Available Plugins (Experimental)” section
Available Plugins (Experimental):
ps Sample limactl-ps alias that shows running instances
sh
limactl info- Includes plugin information in the JSON output
{
"plugins": [
{
"name": "ps",
"path": "/opt/homebrew/bin/limactl-ps"
},
{
"name": "sh",
"path": "/opt/homebrew/bin/limactl-sh"
}
]
}
Plugin Descriptions
Lima extracts plugin descriptions from script comments using the <limactl-desc> format. Include a description comment in your plugin script:
#!/bin/sh
# <limactl-desc>Docker wrapper that connects to Docker daemon running in Lima instance</limactl-desc>
set -eu
# Rest of your script...
Format Requirements:
- Only files beginning with a shebang (
#!) are treated as scripts, and their<limactl-desc>lines will be extracted as the plugin description i.e Must contain exactly<limactl-desc>Description text</limactl-desc> - The description text should be concise and descriptive
Limitations:
- Binary executables cannot have descriptions extracted and will appear in the help output without a description
- If no
<limactl-desc>comment is found in a script, the plugin will appear in the help output without a description
Creating Custom Aliases
To create a custom alias, create an executable script with the name limactl-<alias> and place it somewhere in your PATH.
Example: Creating a ps alias for listing instances
Create a script called
limactl-ps:#!/bin/sh # Show instances in a compact format limactl list --format table "$@"Make it executable and place it in your PATH:
chmod +x limactl-ps sudo mv limactl-ps /usr/local/bin/Now you can use it:
limactl ps # Shows instances in table format limactl ps --quiet # Shows only instance names
Example: Creating an sh alias
#!/bin/sh
# limactl-sh - Connect to an instance shell
limactl shell "$@"
After creating this alias:
limactl sh default # Equivalent to: limactl shell default
limactl sh myinstance bash # Equivalent to: limactl shell myinstance bash
How It Works
- When you run
limactl <unknown-command>, Lima first tries to find a built-in command - If found, Lima executes the external program and passes all remaining arguments to it
- If not found, Lima shows the standard “unknown command” error
This system allows you to:
- Create personal shortcuts and aliases
- Extend Lima’s functionality without modifying the core application
- Share custom commands with your team by distributing scripts
- Package plugins with Lima distributions in the
libexec/limadirectory
Package Installation
Distribution packages and package managers can install plugins in <PREFIX>/libexec/lima/ where <PREFIX> is typically /usr/local or /opt/homebrew. This allows plugins to be:
- Managed by the package manager
- Isolated from user’s
$PATH - Automatically discovered by Lima
Experimental Status
Experimental Feature: The CLI plugin system is currently experimental and may change in future versions. Breaking changes to the plugin API or discovery mechanism may occur without notice.
3 - URL handler plugins
Warning Support for URL handler plugins is experimental
| ⚡ Requirement | Lima >= 2.0 |
|---|
Lima’s template locator supports custom URL schemes through plugins. A plugin named limactl-url-<scheme> handles URLs that begin with <scheme>:. This lets you create short, memorable template locators for your own workflows.
How it works
When Lima encounters a URL with an unrecognized scheme (e.g. dev:webapp), it:
- Searches for an executable named
limactl-url-devusing the standard plugin discovery mechanism - Calls the plugin with the part after the colon as its sole argument (in this case,
webapp) - Reads the plugin’s stdout, which must be either a URL (with any supported scheme) or a local file path
The plugin’s output can itself use a custom scheme. Lima resolves the chain until it reaches a final https: URL or local file path. It detects and rejects redirect loops.
If the plugin exits with a non-zero status, Lima reports the error. Any stderr output from the plugin is included in the error message.
You can use limactl template url to see what a custom URL resolves to without fetching the template:
$ limactl template url dev:webapp
https://github.example.com/raw/infra/lima-templates/master/webapp.yaml
Creating a URL handler
Create an executable script named limactl-url-<scheme> and place it in your PATH.
Returning a URL
The simplest handler maps a short name to a full URL. Here two schemes point at the same repository but select different branches:
limactl-url-dev:
#!/bin/sh
echo "https://github.example.com/raw/infra/lima-templates/master/$1.yaml"
limactl-url-prod:
#!/bin/sh
echo "https://github.example.com/raw/infra/lima-templates/v1.8.3/$1.yaml"
$ limactl start dev:webapp # uses master branch
$ limactl start prod:webapp # uses pinned release
A handler can also generate a pre-signed URL. This s3: handler serves templates from a private S3 bucket:
limactl-url-s3:
#!/bin/sh
aws s3 presign "s3://my-lima-templates/$1.yaml"
$ limactl start s3:webapp
Returning a file path
A handler can return a local file path instead of a URL. This instance: handler retrieves the saved configuration of an existing instance:
limactl-url-instance:
#!/bin/sh
echo "${LIMA_HOME:-$HOME/.lima}/$1/lima.yaml"
This lets you create a new instance using the same template as an existing one:
$ limactl create --name another instance:default
Generating YAML on the fly
A handler can generate a template file at runtime and return its path. This is useful when image URLs contain dynamic components like dates or version numbers that cannot be expressed in static YAML.
limactl-url-nightly:
#!/bin/sh
set -eu
CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/lima/limactl-url-nightly"
mkdir -p "${CACHE_DIR}"
BUILD=$(curl -fsSL "https://builds.example.com/latest-id")
FILE="${CACHE_DIR}/nightly.yaml"
cat <<EOF >"${FILE}"
images:
- location: "https://builds.example.com/${BUILD}/image-amd64.qcow2"
arch: "x86_64"
- location: "https://builds.example.com/${BUILD}/image-arm64.qcow2"
arch: "aarch64"
EOF
echo "$FILE"
The generated file stays in the cache directory. It will be overwritten on the next invocation or cleaned up with the rest of the cache.
A template can reference this handler via the base: field:
base:
- nightly:images
- template:_default/mounts
Composing schemes
Handlers can call limactl template url to resolve other schemes, including github:. This lets a handler build on existing schemes rather than constructing raw URLs itself.
Track the latest release
This handler resolves a github: URL and then replaces the branch with the latest semver tag:
limactl-url-latest:
#!/bin/sh
# Resolve the github: scheme to an https://raw.githubusercontent.com URL
url=$(limactl template url "github:$1")
# Extract "org/repo" from the URL (fields 4-5 of the path)
repo=$(echo "$url" | cut -d'/' -f4-5)
# Find the latest semver release tag (e.g. "v2.1.0"), ignoring pre-releases
tag=$(gh release list --repo "$repo" --json tagName \
--jq 'map(select(.tagName | test("^v[0-9]+\\.[0-9]+\\.[0-9]+$"))) | .[0].tagName')
# Replace the branch/tag segment in the URL with the release tag
echo "$url" | sed -E "s|(https://raw\.githubusercontent\.com/[^/]+/[^/]+/)[^/]+/|\1$tag/|"
$ limactl template url latest:lima-vm/lima/templates/default
https://raw.githubusercontent.com/lima-vm/lima/v2.1.0/templates/default.yaml
Search multiple repos
This handler tries several repositories in order and returns the first match:
limactl-url-my:
#!/bin/sh
template=$1
for repo in \
"github:my-org/templates/%s@main" \
"github:lima-vm/lima/templates/%s@master"; do
url=$(limactl template url "$(printf "$repo" "$template")")
if curl --head --silent --fail "$url" >/dev/null; then
echo "$url"
exit
fi
done
echo "Template $template not found" >&2
exit 1
$ limactl start my:custom-distro # checks my-org/templates first, then lima-vm/lima