Zillowe FoundationZillowe Documentation

Dependencies & Supported Package Managers

How Zoi installs dependencies from external package managers and the full set of supported managers.

Zoi can install dependencies via many ecosystem and OS package managers. This page documents:

  • How to declare dependencies in .pkg.lua
  • All supported managers, their target platforms/ecosystems, and example usage
  • Notes and caveats for specific managers

Declaring dependencies in .pkg.lua

Dependencies are specified in the dependencies section. Both runtime and build dependency groups can be defined as a simple list of required dependencies, or as a more advanced object with required, optional, and selectable options.

Dependency String Format

Each entry follows the format: manager:package with an optional version and an optional inline description.

  • Format: manager:package[@version][:description]
  • Version: Can be specified with @<semver> or a comparator string like =1.2.3, >=2.0.0, ^1.2, ~1.2.3. Do not prefix with v.
  • Description: An inline description can be added after the last colon. It must not contain version characters.
    • Example: pipx:black:Python formatter CLI.
  • Native Packages: Use native:<pkg> to have Zoi automatically select the system's package manager.

Simple Dependency List

For packages with only required dependencies, you can use a simple list of strings.

dependencies({
  runtime = { "native:openssl", "npm:typescript", "zoi:some-zoi-package" },
  build = { "native:make" }
})

Advanced Dependency Object

For more complex scenarios involving optional or selectable dependencies, use nested tables.

dependencies({
  runtime = {
    required = { "zoi:core-utils" },
    options = {
      {
        name = "GUI Toolkit",
        desc = "Choose a GUI provider for the application",
        all = false, -- false means the user must choose one. true allows multiple selections.
        depends = {
          "native:qt6:Recommended for KDE Plasma",
          "native:gtk4:Recommended for GNOME"
        }
      }
    },
    optional = { "zoi:extra-utils:handy extras" }
  },
  build = {
    required = { "zoi:build-utils" }
  }
})
  • required: A list of dependencies that are always installed.
  • options: A list of groups where the user is prompted to choose one or more dependencies.
  • optional: A list of dependencies that the user is prompted to install.

Dynamic Versions with Lua

In .pkg.lua files, you can use Lua's string concatenation and the global PKG table to create dynamic version dependencies. The PKG table contains the fields defined in your package{} block.

Example with dynamic versions:

package({
  name = "my-app",
  versions = {
    stable = "1.4.3",
    beta = "1.5.0-beta.2"
  }
  -- Zoi will resolve the default version (e.g. from the 'stable' channel)
  -- and place it in PKG.version before processing dependencies.
})

dependencies({
  runtime = {
    required = {
      "zoi:my-plugin@" .. PKG.version,
      "npm:my-lib@" .. PKG.version
    }
  }
})

Version Pinning Notes

Zoi parses version specifiers using standard SemVer requirements (e.g. >1.2.3, ~2.4, ^3). However, the ability to enforce these versions depends on the underlying package manager.

Manager FamilyPinning SupportNotes
apt, dnf, yum✔️ YesSupports exact versions via pkg=version or pkg-version syntax.
choco, cargo✔️ YesSupports version constraints via a --version flag.
npm, yarn, pnpm✔️ YesSupports SemVer ranges, tags, and exact versions via pkg@version syntax.
brew❔ PartialPinning is only possible if a formula for the specific version exists (e.g. node@18). It does not support arbitrary SemVer ranges for most packages.
go❌ NoZoi currently installs Go modules using go install <module>@latest. Version specifiers are not supported.
Most OS Managers❌ Nopacman, yay, paru, apk, xbps, eopkg, guix, portage, snap, flatpak, macports, and conda do not support reliable version pinning via Zoi.

When pinning is not supported, Zoi will install the latest version available from the package manager and may print a warning.

Supported managers

Below is a comprehensive list of all supported dependency managers, their target platforms or ecosystems, and an example of how to use them in your .pkg.lua.

ManagerPlatform / EcosystemExample Usage
zoiZoi (all)zoi:my-package
nativeSystem (auto)native:openssl
scriptURL (all)script:example.com/install
apt, apt-getDebian/Ubuntuapt:build-essential
pacmanArch Linuxpacman:base-devel
yayArch Linux (AUR)yay:google-chrome
paruArch Linux (AUR)paru:visual-studio-code-bin
pikaurArch Linux (AUR)pikaur:spotify
trizenArch Linux (AUR)trizen:zoom
aurArch Linux (AUR)aur:slack-desktop
dnf, yumFedora/RHELdnf:libX11-devel
zypperopenSUSEzypper:libopenssl-devel
apkAlpine Linuxapk:build-base
portageGentooportage:dev-libs/openssl
xbps-installVoid Linuxxbps-install:base-devel
eopkgSoluseopkg:system.devel
guixGNU Guixguix:gcc-toolchain
brewmacOS (Homebrew)brew:node
brew-caskmacOS (Homebrew)brew-cask:visual-studio-code
masmacOS App Storemas:1295203466
macportsmacOS (MacPorts)macports:openssl
scoopWindowsscoop:git
chocoWindows (Chocolatey)choco:git
wingetWindowswinget:Git.Git
snapLinux (Snapcraft)snap:node
flatpakLinux (Flathub)flatpak:org.gimp.GIMP
pkgFreeBSDpkg:git
pkg_addOpenBSDpkg_add:git
cargoRustcargo:ripgrep
cargo-binstallRust (binary)cargo-binstall:ripgrep
goGogo:golang.org/x/tools/cmd/goimports
npmNode.jsnpm:typescript
yarnNode.jsyarn:prettier
pnpmNode.jspnpm:eslint
bunBunbun:elysia
voltaJavaScriptvolta:node
denoDenodeno:npm-chalk
jsrJavaScript Registryjsr:@std/http
pipPythonpip:requests
pipxPythonpipx:black
uvPythonuv:ruff
condaCondaconda:numpy
gemRubygem:rails
composerPHPcomposer:laravel/installer
dotnet.NETdotnet:fantomas
nixNixnix:nixpkgs.hello
dart-pubDartdart-pub:shelf

Notes:

  • AUR: aur:<pkg> builds from source using makepkg; uninstall is done with pacman.
  • native:<pkg> selects the appropriate system manager based on OS/distro; if none can be detected, Zoi errors.
  • Some managers (e.g. go, jsr, volta, uv) do not provide reliable uninstall; Zoi prints a notice and skips.
  • The script manager takes a URL as the package name (e.g. script:example.com/install). It appends .sh for Linux/macOS and .ps1 for Windows, then downloads and executes the script. There is no automatic uninstallation.

Zoi Dependencies and Conflict Checks

When a dependency uses the zoi: manager, Zoi resolves the referenced package definition and applies the same conflict checks as for a top-level install:

  • If the dependency package declares bins, Zoi checks whether any of those binaries are already provided by installed packages.
  • If the dependency package declares conflicts, Zoi checks whether any listed packages are installed.

If conflicts are detected, Zoi displays the conflicts and prompts whether to continue before proceeding with installation.

Troubleshooting

  • Some managers require being present on PATH. Run zoi info to see which managers Zoi detects.
  • On macOS, GUI apps use brew-cask; App Store apps require mas to be signed in.
  • On Arch-based systems, you can choose between helpers (yay, paru, pikaur, trizen) or use aur: to build with makepkg.

Last updated on