Project Configuration
Define project commands and environments with zoi.yaml.
Zoi can manage per-project commands and environments using a zoi.yaml file placed in your project root. This page describes the schema and provides examples.
File location
- Create
zoi.yamlin the root of your project repository. - Commands refer to paths relative to the project root unless you use absolute paths.
Schema
The zoi.yaml file allows for simple and complex configurations, including platform-specific commands and environment variables.
# Required project name (used in output)
name: my-project
# Optional: Enable project-level package management
config:
local: true
# Optional: List of packages to install for this project
# Requires `config.local: true`
pkgs:
- eza
- fzf
# Optional: Verify important tools are available
# Each item runs a check command; non-zero exit indicates missing or incompatible
packages:
- name: git
check: git --version
- name: node
check: node --version
# Optional: Short, named commands runnable via `zoi run <cmd>`
commands:
# Simple command
- cmd: test
run: npm test
# Platform-specific command with environment variables
- cmd: dev
run:
# Platform is in format <os>-<arch>, e.g. linux-amd64, macos-arm64, windows-amd64
linux-amd64: npm run dev:linux
macos-amd64: npm run dev:mac
windows-amd64: npm run dev:win
default: npm run dev # Fallback for other platforms
env:
# Simple env vars for all platforms
API_KEY: "12345"
# Platform-specific env vars
platform:
linux-amd64:
ENDPOINT: "https://api.linux.dev"
macos-amd64:
ENDPOINT: "https://api.mac.dev"
default:
ENDPOINT: "https://api.dev"
# Optional: Environment setups runnable via `zoi env <alias>`
environments:
- name: Web development environment
cmd: web
run:
default:
- npm ci
- npm run build
windows-amd64:
- npm ci
- echo "Building for Windows..."
- npm run build:win
env:
default:
NODE_ENV: "production"
windows-amd64:
NODE_ENV: "production_win"
- name: Rust toolchain setup
cmd: rust
run:
- rustup toolchain install stable
- rustup component add clippy rustfmtField Reference
name:string(required)config:object(optional)local:boolean(default:false). Iftrue, enables project-local package management.
pkgs:listofstrings(optional). A list of packages to be installed locally to the project. Requiresconfig.local: true.packages:listof objects (optional). Note: this is for validating tools, not for installing packages. Seepkgsfor installation.name:string(label only)check:string(command to validate presence/version)
commands:listof objects (optional)cmd:string(alias)run:stringormap(command)- If a
string, it's the command for all platforms. - If a
map, keys are platforms (<os>-<arch>) and values are command strings. Adefaultkey can be used as a fallback.
- If a
env:map(optional)- Can be a simple
mapofstring: stringfor environment variables. - Can be a
mapwhere the keyplatformcontains platform-specific environment variables, and other keys are global.
- Can be a simple
environments:listof objects (optional)name:string(label)cmd:string(alias)run:list of stringsormap(commands)- If a
list of strings, it's the command list for all platforms. - If a
map, keys are platforms (<os>-<arch>) and values are lists of command strings. Adefaultkey can be used as a fallback.
- If a
env:map(optional) - Same structure as incommands.
Zoi determines the platform from the OS and architecture (e.g. linux-amd64, macos-arm64, windows-amd64).
Project-local Package Management
Zoi can manage project-specific package dependencies, similar to package.json in Node.js or Cargo.toml in Rust.
To enable this feature, set config.local to true in your zoi.yaml. Then, list the packages your project needs under the pkgs key.
name: my-awesome-project
config:
local: true
pkgs:
- eza
- bat
- fzfWhen this is configured, running zoi install (with no arguments) in the project directory will:
- Read the
pkgslist. - Install the specified packages into a project-local directory. These packages will not affect your global user or system installations.
- Create two files:
zoi.pkgs.json: A detailed manifest of all installed packages, their dependencies, and metadata. This file is intended for local tracking and can be added to your.gitignore.zoi.lock: A file containing cryptographic hashes of the installed packages. This file is used to verify the integrity of the packages and should be committed to your repository.
Commit zoi.yaml and zoi.lock to your repository. This ensures that other developers who clone the project can run zoi install to get the exact same versions of the dependencies, creating a reproducible and secure environment.
The zoi.lock File
The zoi.lock file is a JSON file that records the exact versions and integrity hashes of all the packages installed in a project. It's automatically generated and updated when you run zoi install in a project with local packages enabled.
Its primary purpose is to ensure that every developer on a team has the exact same version of every dependency, providing a reproducible environment. It also serves as a security measure, as it allows zoi to verify that the installed packages have not been tampered with.
Lockfile Schema
version: The version of the lockfile format.registries: A map of registry handles to their URLs.packages: A map of package IDs to their resolved versions.details: A nested map containing detailed information about each package, including its version, integrity hash, dependencies, and any chosen optional dependencies.
Here is a simplified example of a zoi.lock file:
{
"version": "1",
"registries": {
"zoidberg": "https://github.com/Zillowe/Zoidberg.git"
},
"packages": {
"#zoidberg@core/linux:headers": "6.5.9"
},
"details": {
"#zoidberg": {
"@core/linux:headers": {
"version": "6.5.9",
"sub_package": "headers",
"integrity": "sha512-....",
"dependencies": [],
"options_dependencies": [],
"optionals_dependencies": []
}
}
}
}CLI usage
- Run a command by alias:
zoi run dev- To pass arguments to the underlying script, add them after the command alias. Use
--to separate the arguments from Zoi's own options if needed.
# If 'test' is 'npm test', this runs 'npm test --watch'
zoi run test -- --watch
# If 'fmt' is 'cargo fmt', this runs 'cargo fmt --all'
zoi run fmt -- --all- Interactively choose a command (no alias provided):
zoi run- Set up an environment by alias:
zoi env web- Interactively choose an environment:
zoi envIf zoi.yaml is missing, Zoi prints an error. If no commands or environments are defined, the respective subcommands will also error.
Best practices
- Keep
checkcommands fast and side-effect free. - Prefer explicit toolchain versions in environment steps to ensure reproducibility.
- Use short, memorable
cmdaliases. - Split long setups into multiple environments (e.g.
deps,build,lint). - Use the
defaultkey in platform-specific maps to provide a good fallback experience.
Last updated on
