Open source — MIT licensed

One command. Any package. Any distro.

Zero Layer is a universal Linux package manager. It installs software from 13 different ecosystems onto any distribution by translating binaries at install time — not at run time.

curl -Lo zl https://github.com/polpo21/zero_layer/releases/latest/download/zl-x86_64-unknown-linux-gnu

One binary. No runtime, no daemon, no dependencies.

Pulls packages from
  • pacman
  • AUR
  • apt
  • dnf
  • zypper
  • apk
  • xbps
  • portage
  • nix
  • flatpak
  • snap
  • AppImage
  • GitHub
package sources
13
runtime overhead
0ms
tests, CI green
357
background daemons
0

The problem

Linux packaging is fragmented by design

Every distribution ships its own format, its own repository and its own idea of where files belong. The software you want is often packaged — just not for your system.

The package exists, but not for you

A tool is in the AUR, or only as a .deb, or only as a GitHub release. Your distro packaged it two years ago, or never. You end up compiling from source or going without.

The workarounds cost you performance

Containers, virtual machines and compatibility layers all solve this by adding a layer. You pay for it forever: startup latency, memory, disk, and a runtime that must keep running.

Manual installs rot silently

Dropping a tarball into /opt works until a library moves. Nothing tracks the files, nothing knows the dependencies, and nothing can cleanly undo it.

The idea

Translate once, at install time

A Linux binary is not tied to a distribution — it is tied to a handful of concrete facts: which dynamic linker loads it, and where its shared libraries live. Both are recorded inside the ELF file, and both can be rewritten.

Zero Layer reads those fields with goblin, then rewrites them with elb so they point at your system's real linker and library paths. It does this once, while installing.

After that the binary is simply a native binary on your machine. There is no shim, no wrapper script, no sandbox and no supervising process. That is where the name comes from: the layer is zero.

  • No container runtime to install or keep running
  • No performance penalty — it is the same machine code
  • Files land in normal directories you can inspect
  • Everything is tracked, and every install can be rolled back
/usr/bin/rgELF 64-bit LSB · x86-64

built for Arch

PT_INTERP
/usr/lib/ld-linux-x86-64.so.2
RUNPATH
—
NEEDED
libpcre2-8.so.0 · libc.so.6

patched for this machine

PT_INTERP
/lib64/ld-linux-x86-64.so.2
RUNPATH
$ORIGIN/../lib:~/.local/share/zl/lib
NEEDED
libpcre2-8.so.0 · libc.so.6

Same machine code. It just knows where it lives now.

Philosophy

Six principles behind every decision

Zero Layer is opinionated. These are the rules the codebase is held to.

Zero overhead after install

All translation work happens once, during installation. Nothing sits between your program and the kernel afterwards.

Detect, never assume

Architecture, dynamic linker, libc, library directories and filesystem layout are all probed from the running system instead of hardcoded.

Atomic or nothing

Every install runs inside a transaction that records what it touched. A failure anywhere unwinds the whole operation.

One binary, no system libraries

redb instead of SQLite, elb instead of patchelf, rustls instead of OpenSSL. Written in Rust; the few native pieces (compression, crypto) are compiled in, so there is nothing to install next to it.

The user picks the source

When a package exists in several ecosystems, Zero Layer shows all of them and lets you choose. It never silently decides for you.

Reversible by default

History, rollback, orphan detection and dry-run are core features, not afterthoughts. You can always see what happened and undo it.

How it works

What happens when you type install

Eight stages run between your command and a working binary. Each one is observable with -v, and any failure rolls the whole thing back.

  1. Resolve

    Finds the package and walks its dependency tree recursively, detecting cycles. If a dependency is missing from the primary source, every other enabled source is queried and you choose.

    cross-source resolution
  2. Check conflicts

    Five classes are checked before anything is written: file ownership, binary names, library sonames, declared conflicts and version constraints.

    5 conflict types
  3. Download

    Packages are fetched straight from their native repositories over four parallel threads, with progress bars and automatic retry with backoff.

    4 threads · retry
  4. Verify

    SHA256 checksums are enforced and GPG signatures are checked when the source provides them. An unverifiable signature is reported differently from a bad one.

    SHA256 + GPG
  5. Extract

    The archive format is detected and unpacked — deb, rpm, tar, zst, xz, nar, squashfs, zip or AppImage — then normalised to a standard FHS layout.

    9 archive formats
  6. Patch

    Every ELF binary is analysed, then its interpreter and RUNPATH are rewritten to match your system. Multi-binary packages are patched in parallel; static binaries are correctly left alone.

    goblin + elb
  7. Install

    Files are placed atomically inside a transaction that records every file, directory, symlink and database row it creates. Any error unwinds all of it.

    atomic · rollback
  8. Track

    Files, dependencies, ownership and the operation itself are written to an embedded database, which is what makes why, size, doctor and rollback possible later.

    redb + graph

Capabilities

A complete package manager, not a demo

Everything you would expect from your distro's tooling, plus the things it never had.

Native binary translation

ELF binaries are analysed with goblin and patched with elb at install time. The dynamic linker and RUNPATH are rewritten to match your system, so packages run at full native speed afterwards.

  • goblin
  • elb
  • PT_INTERP
  • RUNPATH

13 sources in parallel

Every enabled source is queried simultaneously, results are scored by relevance, and AUR binary variants are discovered automatically.

Atomic transactions

An install either completes or leaves no trace. No half-written state, ever.

Diagnostics built in

doctor, audit, why, size, diff and history answer the questions package managers usually leave you guessing about.

  • zl doctor
  • zl why
  • zl size
  • zl audit
  • zl diff

Multi-version & environments

Install versions side by side and switch between them, or spin up an ephemeral environment that disappears when you exit the shell.

Security aware

Checksums and signatures on the way in, CVE lookups against OSV.dev on the way out, plus pinning to freeze anything you do not want moving.

Sources

Thirteen ecosystems, one interface

Each source is a plugin implementing the same trait. Enable the ones you want per machine, or filter per command with --from.

  • pacmanArch Linux
  • aurArch User Repository
  • aptDebian · Ubuntu
  • dnfFedora · RHEL
  • zypperopenSUSE · SLES
  • apkAlpine Linux
  • xbpsVoid Linux
  • portageGentoo binhost
  • nixnixpkgs
  • flatpakFlathub
  • snapSnapcraft Store
  • appimageAppImageHub
  • githubGitHub Releases
  • See live plugin status

Source availability depends on the upstream being reachable. The repository tracks the live status of every plugin.

Commands

The interface, end to end

One binary, twenty-five commands, shell completions for bash, zsh and fish.

$ zl install firefox                 # pick from every source
$ zl install firefox --from pacman   # force one source
$ zl install sharkdp/bat --from github
$ zl install python --version 3.12  # side by side
$ zl remove firefox --cascade       # drop orphaned deps
$ zl --dry-run install firefox     # preview only
$ zl run neofetch                   # run without installing

Under the hood

Built to be boring in the right places

Predictable layout on disk, a Rust codebase with native code kept to a minimum, and a test suite that runs on every push.

Where things land

Everything lives under one directory you own. Add bin to your PATH and nothing else on the system is touched.

Design constraints

  • Single binary; no system libraries to install
  • RUNPATH over RPATH, so LD_LIBRARY_PATH still works
  • Threads instead of an async runtime
  • Everything auto-detected from the running system
  • Rollback is a first-class path, not an error case
  • Zero clippy warnings, formatted, CI-gated
~/.local/share/zl/
├── bin/        symlinks — add to PATH
├── lib/        shared libraries
├── share/      data files
├── etc/        configuration
├── packages/   one dir per name-version
├── cache/      downloads
├── envs/       ephemeral environments
└── zl.redb     package database

The stack

  • Rust 2024
  • goblin
  • elb
  • redb
  • petgraph
  • clap
  • reqwest + rustls
  • indicatif
  • quick-xml
  • sha2
  • zstd
  • tar
  • cpio

Comparison

How it differs from the alternatives

Containers and universal package formats solve the same problem by isolating software. Zero Layer solves it by adapting software.

Tool Approach Runtime cost Disk cost Needs a daemon
Zero Layer Patch binaries at install None Shared libraries, deduplicated No
Docker / Podman Full OS image per app Process + namespace overhead Image layers per app Yes
Flatpak Bundled runtimes Sandbox + portal indirection Runtime per app family Yes
Snap Squashfs + confinement Mount + confinement layer Compressed image per app Yes
Manual tarball Unpack and hope None Whatever you copied No

Manual installs match Zero Layer on overhead — and lose on everything else: nothing is tracked, nothing resolves dependencies, and nothing can undo it.

Get started

Running in under a minute

One download, one line in your shell profile. No package manager needed to install the package manager.

v0.3.1 is published, with prebuilt binaries for x86_64 and aarch64, glibc and musl. Everything described on this page ships in it — no compiler needed. Release notes →

  1. Install the binary

    Grab the latest release for your architecture. Use the second form if you would rather not use sudo.

    $ curl -Lo zl https://github.com/polpo21/zero_layer/releases/latest/download/zl-x86_64-unknown-linux-gnu
    $ chmod +x zl && sudo mv zl /usr/local/bin/
    
    # or, without sudo:
    $ mkdir -p ~/.local/bin && mv zl ~/.local/bin/
    
    # other builds: zl-x86_64-unknown-linux-musl,
    # zl-aarch64-unknown-linux-gnu, zl-aarch64-unknown-linux-musl
  2. Put it on your PATH

    Zero Layer symlinks the executables it installs into its own bin directory.

    # bash (~/.bashrc) or zsh (~/.zshrc)
    export PATH="$HOME/.local/share/zl/bin:$PATH"
    
    # fish
    fish_add_path ~/.local/share/zl/bin
  3. Install something

    Leave off --from and Zero Layer will search every enabled source and let you pick.

    $ zl install ripgrep
    $ zl install sharkdp/bat --from github
    $ zl doctor                # confirm everything is healthy

Prefer to build it yourself? Requires Rust 1.90 or newer. cargo build --release →

FAQ

Reasonable questions

Does this replace my distro's package manager?
No, and it does not try to. Zero Layer installs into your home directory and never touches system paths, so pacman, apt or dnf keep managing the base system exactly as before. Use it for the software your distro does not package.
Do I need root?
No. The default installation lives entirely under ~/.local/share/zl. Root is only relevant if you choose to put the zl binary itself in /usr/local/bin, and even that is optional.
Is it really zero overhead?
Yes, because after installation there is nothing left running. The patched binary is ordinary machine code executed directly by the kernel — no sandbox, no supervisor, no translation at run time. The work happens once, while installing.
What if a package needs a library I do not have?
Dependencies are resolved recursively before anything is downloaded, and if one is missing from the primary source, every other enabled source is searched. After install, a post-check warns about any shared library it still cannot locate.
What happens when an install fails halfway?
Nothing is left behind. Every install runs inside a transaction that records the files, directories, symlinks and database entries it created, and any failure unwinds all of them. You can also preview any operation with --dry-run.
Which distributions does it support?
Any of them, in principle. Rather than keeping a list, Zero Layer detects the architecture, dynamic linker, libc, library directories and filesystem layout at runtime — including merged-usr, NixOS, Guix, GoboLinux and Termux layouts.
Is it production ready?
It is early software under active development, and honest about it: the repository tracks exactly which source plugins are verified against their live upstreams and which are still being repaired. The core install path is covered by 357 tests that gate every commit.
How do I get rid of it?
Delete the directory. Everything Zero Layer installs — packages, database, cache, symlinks — lives under one folder, so removing it removes every trace.

Install anything, on anything

Free and open source under the MIT licence. No account, no telemetry, no daemon.