Skip to main content

Pre-1.0

envy is under active development

Call it somewhere between late alpha and early beta. Everything on this site describes what envy actually does today, and it does work, but expect rough edges: bugs, missing pieces, and breaking changes to the CLI, the manifest format, and the Lua API between versions.

Nothing here is stable yet. Pin a version, read the release notes before you move off it, and please file what you find.

Ruckus, the envy mascot

envy

what's yours... is mine.

loading the recordingA terminal session. cmake is not installed. Entering a project directory
and running cmake --version downloads envy, installs cmake, and runs it.
The second run is instant. Leaving the directory takes cmake away again.

envy is an unopinionated, hermetic, per-project, serverless package manager.

  • Unopinionated. A toolchain, a vendor SDK, an interpreter, a Homebrew formula, a udev rule: each is a package if a handful of Lua verbs can describe it.
  • Hermetic. One envy.lua pins the whole toolchain, envy included, by version and checksum. Clone the repo and run a tool.
  • Per-project. Every project declares its own world, into a content-addressed cache, so ten projects pinning one compiler store it once. A project that wants its packages inside its own tree says so in one line.
  • Serverless. No registry, no daemon, no server. Specs fetch bits from wherever they already live and verify them.

It ships as one batteries-included executable per platform: macOS, Linux, and Windows, on arm64 and x86_64. Lua, the archive formats, git, and S3 are compiled in, so there is nothing to install and no daemon to run. The committed bootstrap script downloads the build your project pins.

An optional package depot lets CI publish prebuilt artifacts that everyone else's sync downloads instead of building. An accelerator you can add, never a requirement.

See it work​

Four real sessions, recorded end to end against the public first-party specs. The elapsed times on screen are the ones the machine actually took.

Two projects that need two different pythons, and a machine python that neither of them touched. Switching between them is a cd, because the shell hook puts each project's bin directory on PATH as you arrive.

loading the recordingA terminal session. python3 -V prints the system Python, then a different
version inside each of two project directories, then the system one again
after leaving.

Why envy?​

One job: give a project the tools it declares, on any machine, without disturbing anything else on it.

Attestable end to end, as far as you want it. Every link in the chain can be pinned by content hash, envy's own binary included. The committed bootstrap script verifies the release against @envy sha256sums before it runs anything, a bundle from git requires a full commit sha, a spec carries a sha256 or a commit sha of its own, and each spec's downloads are pinned in its fingerprint table. Pinning is per link, so a project tightens it as far as it needs and no further. Supply-chain resilience has the whole chain.

Not a system package manager. Homebrew and apt own one global set of packages and are built around moving you forward. envy never updates anything. A version is an option in a manifest, changed by editing that manifest. There is no envy upgrade and no "outdated".

Alongside Nix. Nix takes on a larger problem than envy does and takes it on thoroughly. envy's scope is one project's tools, and it stays small enough to commit: a single executable, one bootstrap script, no daemon, no store to initialize, nothing that needs root. macOS, Linux, and Windows all run the same binary against the same manifest. Packages are ordinary directories, so anything that takes a path can use them.

Not Hermit. envy takes Hermit's best idea, the committed bootstrap script, but a Hermit package is a descriptor while an envy spec is a program. Any verb can be a Lua function, so a spec can accept a license over POST, drive a platform installer, or install a udev rule. Declarative shapes remain for the simple cases, and four-line specs are common.

So: apt or Homebrew for your machine, envy for your project.

A standalone toolbox​

A package manager has to download from anywhere, unpack anything, verify bytes, and run scripts. envy exposes all of it, no manifest or project required:

CommandWhat it does
envy fetchDownload over https, http, ftp, ftps, s3://, git://, git+ssh://, or a local path
envy extractUnpack tar, tar.gz, tar.xz, tar.bz2, tar.zst, zip, 7z, rar, iso, and bare compressed streams, with glob selection
envy hashPrint sha256sum-style lines, ready to paste into a spec or a depot index, or one BLAKE3 digest for a whole directory
envy git-resolveTurn a remote branch or tag into a full commit sha without cloning
envy luaRun a Lua script with envy's whole API available

All compiled in rather than shelled out to: the AWS SDK for s3:// with your ambient credentials, libgit2 for git, libarchive for formats. No CLI tools required on the host. Specs reach the same machinery through envy.fetch and friends.

Supply-chain resilience​

No advisory feed, no scanner. The protection is structural: no registry to compromise, nothing resolved by name alone, and every link pinnable by content hash and committed to your repo.

  • Nothing is fetched by name. No index, so no namespace to squat and no "latest" a publisher can push at you. A spec comes from a URL, a commit, or a bundle you named.
  • envy verifies itself. @envy version and @envy sha256sums pin the release, and the bootstrap script verifies every binary before running it. Retargeting is one command and a reviewable diff.
  • Pins go all the way down. Specs carry a sha256 or a full commit sha, bundles require one, and a spec's downloads are pinned in its own fingerprint table. An unhashed download is re-fetched rather than trusted from cache.
  • Prebuilt artifacts are an accelerator, not an authority. A depot hit is checked against its hash, and a mismatch builds from source. A private mirror republishes the checksum file byte for byte, so one pin validates against both.
  • Nothing modifies your machine by accident. Packages land in a cache you can delete. Host-level work lives in a named SETUP pair that runs only when a manifest entry selects it.

One limit: specs are Lua and envy runs them, which is how a spec handles a license-acceptance POST. A spec source you do not control is code you do not control. Pin it, review the diff when it moves, and keep your own specs under local.*. Reproducibility has the full trust chain.

The name, and the raccoon​

Your project wants a pile of shiny things off the internet. envy goes and gets them, then pins the pile into a hermetic environment.

Ruckus is a raccoon. Raccoons take shiny things that are not theirs and have no idea what any of them do. Neither does envy. A compiler, a udev rule, and a license-gated vendor blob are all just shiny things to it.

Are you an AI coding agent?

Read envy for agents, a one-page, maximally dense summary of everything on this site.

Conventions​

Examples call tools by bare name, envy sync and cmake --version, assuming the shell hook is installed. Without it, prefix the project's bin directory: ./bin/envy sync, or bin\envy.bat sync on Windows. Snippets are POSIX for brevity, and every command behaves the same on Windows.

Where to go​