Elpe. Yaks big. Razors bigger

Sunday, June 8, 2025
By Pierre-Étienne Meunier

TL;DR: New config-as-code immutable build system in Rust and OCaml, see https://nest.pijul.com/pmeunier/elpe

Elpe is a library to describe build environments from other Linux distributions, and run scripts in these environments in containers. This project tries to bridge the gap between a purely functional, almost fully bootstrapped Linux distributions like Nix, and a more mainstream package manager like Debian and Ubuntu.

I started thinking about this topic when trying to add a CI system to the open source Nest, which I’ll blog about in a near future.

A trade-off in Linux software distribution

There is a trade-off between two widely different visions of what software distribution should look like on Linux:

Many other projects, such as Fedora Silverblue, Docker or Gentoo solve this trade-off in various ways, making different assumptions I won’t dive into.

On a personal note, I’ve been a Debian user between 2000 and 2014, and a NixOS user and contributor since then (and never reinstalled my laptop ever since then, and it’s still my daily driver).

The problem with existing solutions

The two solutions I am going to talk about now are more than 20 years old. Debian started in 1993, and NixOS in 2003.

One massive problem with Debian/Ubuntu is the lack of build reproducibility and atomic updates. This means that, in particular:

This implies that getting a full view of what is on your computer takes a lot of rigorous work (a bit like when working with Git, but at an even larger scale).

NixOS solves these quite elegantly, but faces multiple subtle, mostly non-technical problems:

A different take on the distribution trade-off

When thinking about the CI system for the Nest, I wanted to explore a different take on the trade-off I explained above. I don’t really think the problems of Nix and Nixpkgs stated above come from bad design or engineering, so I’m definitely not planning on doing “Nix, but right” (besides, other projects are already doing that, see Tvix and Lix).

The goal of Elpe is to use the excellent idea (taken from Nix) of hard-coding paths into bash scripts and running them in containers, but using Ubuntu packages instead of bootstrapping the entire package collection, making the separation between my own build code and the system’s clearer: we don’t even use the same parts of the Elpe API to describe these two operations.

Also, I wanted to use that as an opportunity to rethink some of the bits I don’t quite like, such as the suboptimal language design and some security issues.

I’ve explained some of the design choices in the project’s README.

Which platforms does this run on?

This is a Linux project for now, but could easily be extended with other platforms.

Elpe could probably be ported to other operating systems, with some trade-offs in terms of performance and security due to the lack of process namespacing. Please reach out if you’re interested in this.

An example

Here’s a “Hello, world!” package compiled using Elpe.

First write the following Makefile:

all:
	gcc -o hello hello.c

install:
	install -D --mode 555 hello ${DESTDIR}/usr/bin/hello

And a file named hello.c:

#include <stdio.h>

int main() {
  printf("Hello, world!\n");
}

Then, write the following OCaml file, named elpe.ml:

open Elpe
open Lwt.Syntax

let _ =
  build
    (object (self)
       inherit std_derivation
       method name = "test"
       method! src = self#local_src "."
       method! build_inputs =
         Lwt.return
           [
             (ubuntu "gcc" :> derivation);
             (ubuntu "libc6-dev" :> derivation);
             (ubuntu "make" :> derivation);
             (ubuntu "coreutils" :> derivation);
             (ubuntu "libstdc++-13-dev" :> derivation);
           ]
    end)

Then, start the Elpe daemon:

$ sudo elpe-server -c config.toml

With the appropriate config.toml (example in the main Elpe repo). You can leave the daemon running.

Finally, build the package:

$ elpe build

Help wanted!

Feel free to reach out in the Pijul Zulip if you’re interested in helping. I’ve listed a few of the items that need help in the project’s README.