Skip to content

provider.star — Core API Reference

Back to Overview

This document covers the execution model, file structure, top-level variables, provider functions, and the ctx context object.


Table of Contents


1. Execution Model

vx uses a two-phase execution model (inspired by Buck2):

┌──────────────────────────────────┐     ┌──────────────────────────────────┐
│  Phase 1 — Analysis (Starlark)   │     │  Phase 2 — Execution (Rust)      │
│                                  │     │                                  │
│  provider.star runs and produces │────▶│  Rust interprets descriptors     │
│  descriptor dicts (pure compute, │     │  and performs real I/O:          │
│  no I/O, no network)            │     │  HTTP, filesystem, processes     │
└──────────────────────────────────┘     └──────────────────────────────────┘

Key implications:

PrincipleDetail
No side effectsStarlark functions return descriptor dicts, they never call the network or filesystem directly
DeterministicGiven the same ctx, a function always returns the same result
JSON round-tripAll values pass through JSON serialization between Starlark and Rust
None = unsupportedReturning None from download_url() means "not available on this platform"

2. File Structure

Every provider lives in a single directory:

crates/vx-providers/<name>/
├── provider.star     # All logic (REQUIRED)
├── provider.toml     # Optional metadata supplement
└── README.md         # Optional documentation

User-defined providers follow the same structure under ~/.vx/providers/<name>/.


3. Top-Level Variables

These are declared as module-level assignments, not functions.

VariableTypeRequiredDescription
namestringYesProvider name (must match directory name)
descriptionstringYesHuman-readable description
runtimeslist[dict]YesRuntime definitions (see runtime.star)
permissionsdictNoPermission declarations (see permissions.star)
homepagestringNoProject homepage URL
repositorystringNoSource repository URL
licensestringNoSPDX license identifier (e.g. "MIT", "Apache-2.0")
ecosystemstringNoCategory: nodejs, python, rust, go, devtools, system, custom, etc.
package_aliasdictNoRoute to ecosystem package runner (e.g. {"ecosystem": "uvx", "package": "ruff"})
package_prefixeslist[string]NoPrefixes for package execution (e.g. ["bun", "bunx"])
vx_versionstringNoMinimum vx version requirement (e.g. ">=0.7.0")
python
# Example
name        = "ripgrep"
description = "ripgrep — recursively search directories for a regex pattern"
homepage    = "https://github.com/BurntSushi/ripgrep"
repository  = "https://github.com/BurntSushi/ripgrep"
license     = "MIT OR Unlicense"
ecosystem   = "devtools"

4. Provider Functions

These are module-level functions called by the Rust runtime.

FunctionSignatureRequiredReturns
fetch_versions(ctx) → descriptorYesVersion list or fetch descriptor
download_url(ctx, version) → string | NoneYesDownload URL, or None if unsupported
install_layout(ctx, version) → dict | NoneYesInstall layout descriptor
environment(ctx, version) → list[EnvOp]YesEnvironment variable operations
store_root(ctx) → stringNoStore root directory path
get_execute_path(ctx, version) → stringNoFull path to executable
post_install(ctx, version) → dict | NoneNoPost-install actions
post_extract(ctx, version, install_dir) → listNoPost-extract hook actions
pre_run(ctx, args, executable) → listNoPre-run hook actions
deps(ctx, version) → list[DepDef]NoRuntime dependency declarations
system_install(ctx) → dictNoSystem package manager strategies
script_install(ctx) → dictNoScript-based install commands
uninstall(ctx, version) → boolNoCustom uninstall logic

Minimal provider skeleton

python
load("@vx//stdlib:provider.star",
     "runtime_def", "github_permissions",
     "github_rust_provider")

name        = "mytool"
description = "My awesome tool"
ecosystem   = "devtools"

runtimes    = [runtime_def("mytool")]
permissions = github_permissions()

_p = github_rust_provider("owner", "repo",
    asset = "mytool-{vversion}-{triple}.{ext}")

fetch_versions   = _p["fetch_versions"]
download_url     = _p["download_url"]
install_layout   = _p["install_layout"]
store_root       = _p["store_root"]
get_execute_path = _p["get_execute_path"]
environment      = _p["environment"]

5. Context Object (ctx)

The ctx object is injected by the Rust runtime. It uses Starlark struct syntax (dot access).

FieldTypeDescription
ctx.namestringProvider name
ctx.descriptionstringProvider description
ctx.versionstringVersion being processed
ctx.runtime_namestringRuntime name (for multi-runtime providers)
ctx.version_datestringBuild tag or date of the version
ctx.vx_homestringvx home directory (~/.vx)
ctx.install_dirstringVersion-specific install directory
ctx.platform.osstring"windows" | "macos" | "linux"
ctx.platform.archstring"x64" | "arm64" | "x86"
ctx.platform.targetstringRust target triple (e.g. "x86_64-pc-windows-msvc")
ctx.envdictCurrent environment variables
ctx.paths.install_dirstringSame as ctx.install_dir
ctx.paths.vx_homestringSame as ctx.vx_home
ctx.paths.store_dirstringGlobal store directory
ctx.paths.cache_dirstringCache directory
ctx.paths.download_cachestringDownload cache directory

Usage

python
def download_url(ctx, version):
    key = "{}/{}".format(ctx.platform.os, ctx.platform.arch)
    # ...

See Also

Released under the MIT License.