If you’re a curious user - especially one who’s into customizing your Debian - you’ve probably run into this situation at least once: you discover a cool software, but it’s either not available in your Debian’s package repositories, or it is there, but the version is outdated.

Newer versions often bring in completely new features that you actually want to use. When I think of Debian Stable, a few examples come to mind.

Terminal emulator Alacritty, for instance. The version in the Debian Stable repo is dated— Alacritty of this version uses a .yml config file, but newer versions have switched to .toml.

Or btop—the version in Debian Stable doesn’t support NVIDIA GPU monitoring, while the current version does.

And then there's Hyprland, a window manager that’s only available in Debian Unstable and Testing (Trixie). On Debian Stable, it’s not even in the repos at all.

This article is dedicated to a terminal-based file manager yazi that is super mega cool, but it’s not available in any of Debian’s repositories - not in Stable, not in Testing, not even in Unstable.


NB! Building applications from source isn’t necessarily hard in terms of the actual process—but making them work, and more importantly, making sure they don’t break your system, is another story.

Small utility apps that are meant to run in user space (i.e. they don’t touch anything kernel-related like modules—are generally less risky in terms of stability of your Debian afterwards). The main problem is that there’s no guarantee they’ll work properly due to dependencies. The more dependencies an app has, the higher the risk that it won’t work at all.

Also, be very careful when a piece of software wants to downgrade some packages as part of its dependency list. I strongly recommend avoiding that. Downgrading system packages can mess up your system a lot.

Before building anything from source, always evaluate potential security risks. Don’t rush into compiling some random app that has minimal activity on GitHub—especially without reviewing the source code carefully.

NB2! I’m currently using Debian Testing (aka Trixie), which is to become Debian 13—I hope soon. If you’re trying to get Yazi working on Debian Stable, I can’t guarantee it’ll work due to dependency versions.


What’s so particular about building software from source in a debootstrapped Debian, and what does that even mean?

If you’ve ever developed something in Python—or used Node.js—then this will probably make sense to you. You might be familiar with Python virtual environments, or how Node.js projects usually live in their own directories with all the installed libraries.

When you’re working inside a Python environment and need some libraries, you install them into that isolated environment. Move to another project? Create a new environment, install only what you need, and that’s it. No system-wide Python mess. Same story with Node.js—you usually don’t install JS libraries globally, they just live in the project folder. Clean, contained.

Now, Debian bootstrapping offers a kind of similar idea—but in the context of system-level stuff.

Let’s say you want to install Yazi, which is written in Rust. You’ll need Rust installed on your system to build it. Or maybe you want to build Ly display manager, written in Zig—you’ll need to install the Zig compiler. Other programs written in C? You’ll need a C compiler and a bunch of build-time libraries.

But here’s the key point: software often has one set of requirements to build and a completely different set of requirements to run.

For example, with Yazi, you only need Rust to build it. Once that’s done, Rust isn’t required to run the app. So, what do you do? Install Rust, build the thing in 10 minutes, and then… what? Leave Rust on your system? Delete it? What if the software needed tons of other build-time tools that you’ll never use again?

That’s where debootstrap comes in. It lets you create a sort of mini Debian environment—a clean, isolated system within your system. It’s not a full second Debian install, but it is like a mini mirror of your Debian system where you can install/build/test whatever you want without messing up your main OS. It’s like a virtual "project" space for your system-level experiments.


debootstrap is a tool which will install a Debian base system into a subdirectory of another, already installed system. It doesn't require an installation CD, just access to a Debian repository. It can also be installed and run from another operating system, so, for instance, you can use debootstrap to install Debian onto an unused partition from a running Gentoo system. It can also be used to create a rootfs for a machine of a different architecture, which is known as "cross-debootstrapping". (Debian Wiki: Debootstrap)

First, you need to install debootstrap package:

$ sudo apt install debootstrap

Then, I think it is convenient to elevate your user and execute commands as root user ($ changes for # in code snippets, meaning that these commands are run by root user)

First, I create a directory where my bootstrapped Debian will reside:

# mkdir /trixie-chroot
## If you use Debian Stable:
# mkdir /stable-chroot

## And then, I "deboostrap" Debian into this directory
## NB! I use Trixie, and I Debootstrap Trixie!!!

# debootstrap trixie /trixie-chroot http://deb.debian.org/debian/
## If you use Debian Stable:
# debootstrap stable /stable-chroot http://deb.debian.org/debian/

As I mentioned, bootstrapped Debian is not a fully functional system and cannot function outside of the "main" Debian on which it resides. That is due to the fact that it is exactly your main OS sharing with bootstrapped Debian some its components in order to enable a simulation of a complete runtime environment inside the bootstrapped Debian, allowing it to behave like a real system.

This is achieved by mounting pseudo filesystems to bootstrapped Debian, or more correctly, chroot.

chroot on Unix-like operating systems is an operation that changes the apparent root directory for the current running process and its children. (Debain Wiki: chroot)

It may sounds complicated and scary, but actually it is just a couple of commands mount.

First thing to do is to mount the proc filesystem inside the chroot (/trixie-chroot in my case). The proc filesystem provides access to kernel and process information. Many system tools (like ps, top, etc.) rely on /proc to function correctly. Without it tools inside the chroot won’t be able to access process info or kernel parameters.

Second, is to mount the sysfs filesystem to /trixie-chroot. sysfs exposes kernel devices and attributes. It's required by many parts of the system like udev, systemd, etc. Without it hardware-related commands (or anything interacting with kernel devices) may not work inside the chroot.

Third, you need to provide information to chroot Debian about DNS nameservers, especially if you have some custom configuration. Otherwise you will not be able reach internet from chroot and install packages.

All these complex sounding things can be done with 3 commands:

# mount proc /trixie-chroot/proc -t proc
# mount sysfs /trixie-chroot/sys -t sysfs
# cp /etc/hosts /trixie-chroot/etc/hosts

Now, you can "login" into bootstrapped Debian!

# chroot /trixie-chroot /bin/bash

Now, we can start building Yazi from source! I’ll be following the official installation guide...
...with one interesting modification you might find useful for other Rust-native apps.

But let’s get started.

First, it's important to note that Yazi has various dependencies—because as a terminal file manager, it can do things like preview images and different file types right inside the terminal! And of course, this kind of functionality requires some additional software to be installed.

For me, the dependencies of Yazi looked pretty familiar. You can check them one by one if you’re unsure.
So why am I installing them into a Debian chroot if I don't actually plan to use it?
Well, I'm not that advanced when it comes to Rust apps. I’ve got more experience building from source using make, and if you’ve ever done that, you probably know about the ./configure step—it scans your system and sets the right parameters for the build.

What often happens is, if something’s missing on your system, that is not required by any core feature of to be built software, these features are just get skipped during build processes, because requirements for them are not satisfied. I’m not sure if Rust works exactly the same way, but either way, it’s not a big deal—I’m planning to destroy this chroot after installation anyway.

chroot # apt update
chroot # apt install ffmpeg 7zip jq poppler-utils fd-find ripgrep fzf zoxide imagemagick

Here comes NB for Debian Stable users:

Note that these dependencies are quite old on some Debian/Ubuntu versions and may cause Yazi to malfunction. In that case, you will need to manually build them from the latest source. (Yazi Installation guide)

As the next step, I need to install Rust, of course:

chroot # apt install curl
chroot # curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
chroot # rustup update

And after this... I diverge from the official installation guide. Actually, this project is awesome, and installing it is super easy—to the point that it will literally leave only Rust installed on your system afterwards. Here's the command from the installation guide -
cargo install --locked yazi-fm yazi-cli. As you can see, this installs two packages directly on your system.

However, in my chroot setup, this is kind of useless—because if I run that command, it’ll install those packages inside the chrooted Debian, which I obviously won’t be using.

But here’s the cool part: Rust has this amazing crate called cargo-deb.

Debian packages from Cargo projects
This is a Cargo helper command which automatically creates binary Debian packages (.deb) from Cargo projects. (Rust Docs: cargo-deb)

Now you can probably guess what my goal is — I want to get two .deb files: one for yazi-fm and one for yazi-cli. Then I can just copy them over to my main system and install them with dpkg. Simple and clean!

To do that, first I need to install cargo-deb from crates.io.

chroot # rustup update  
chroot # apt install build-essentials # gcc compiler
chroot # cargo install cargo-deb

After this, I clone the Yazi project's GitHub repo:

chroot # git clone https://github.com/sxyazi/yazi.git
chroot # cd yazi

And then ... I just instruct Rust to build from source 2 .deb files:

chroot # cargo deb -p yazi-fm --locked
chroot # cargo deb -p yazi-cli --locked

After these two process are completed 2 .deb files are placed into ./target/debian directory of yazi root directory.

What is left is to copy these two files to the main system and install 2 packages from them using dpkg.

chroot # exit
# exit 
$ cd # teleporting to home directory of my regular user
$ sudo cp /trixie-chroot/root/yazi/target/debian/yazi-cli_25.4.8-1_amd64.deb .
$ sudo cp /trixie-chroot/root/yazi/target/debian/yazi-fm_25.4.8-1_amd64.deb .

$ sudo dpkg -i yazi-fm_25.4.8-1_amd64.deb
$ sudo dpkg -i yazi-cli_25.4.8-1_amd64.deb

Voila!

Command to launch Yazi File manager: yazi
Command to launch Yazi CLI: ya

Image description