The Shani OS Software Ecosystem — What to Use, When, and Why

Shani OS's root filesystem is read-only. You cannot write to /usr, /bin, or /lib at runtime — the OS is a verified, immutable image. So how do you install software?

The answer is that software belongs in one of several persistent layers, each in its own Btrfs subvolume alongside the OS. Every one of these layers survives OS updates and rollbacks completely untouched. None of them conflict.

This post is the single reference for all of them.


Decision Flowchart

Start here when you need to install something:

What do you need?
│
├─ A GUI desktop application
│   └─ Is it on Flathub?
│       ├─ Yes → Flatpak (flatpak install flathub ...)
│       └─ No → Is it on the Snap Store?
│               ├─ Yes → Snap (snap install ...)
│               └─ No → Is it an AppImage?
│                       ├─ Yes → AppImage + Gear Lever
│                       └─ No → Distrobox (install inside a container, export to launcher)
│
├─ A CLI tool or development runtime
│   └─ Is it in Nixpkgs? (search.nixos.org)
│       ├─ Yes → Nix (nix-env -iA nixpkgs.toolname)
│       └─ No → Distrobox (install via apt/pacman/yay inside a container)
│
├─ A Windows application (.exe)
│   └─ Does it work under Wine?
│       ├─ Likely yes → Bottles (Wine environment manager, pre-installed on KDE)
│       └─ Needs real Windows kernel → Virtual Machine (virt-manager / GNOME Boxes)
│
├─ A database, service, or backend
│   └─ Podman (rootless OCI containers, Docker-compatible)
│
├─ A containerised HPC/research environment for cluster use
│   └─ Apptainer (single .sif file, runs identically on any SLURM/PBS cluster)
│
├─ A full mutable Linux environment (need apt/pacman/yay/AUR)
│   └─ Distrobox (full distro package manager, home dir shared)
│
├─ A full isolated Linux system (own init, services, network)
│   ├─ Need rich tooling (image catalog, port forwarding) → LXC/LXD
│   └─ Need minimal overhead, no daemon → systemd-nspawn
│
└─ An Android app
    └─ Waydroid (full hardware-accelerated Android in a container)

The Full Comparison Table

EcosystemBest forIsolationGUI appsCLI toolsRoot requiredSurvives updates
FlatpakGUI desktop appsSandboxed✓ primaryNo@flatpak
SnapGUI apps not on FlathubStrict/ClassicSomeNo@snapd
AppImagePortable/beta appsNone (user perms)No@home
NixCLI tools, dev runtimesNone (profile)Some✓ primaryNo@nix
HomebrewmacOS muscle memoryNone (user dir)SomeNo@home
DistroboxFull distro env, AURLow–medium✓ (export)✓ (export)No@containers
PodmanServices, databasesOCI containerNo (rootless)@containers
LXC/LXDFull system containersHighYes (lxd group)@lxc/@lxd
systemd-nspawnLightweight system containersHighYes@machines
ApptainerHPC / cluster workloadsRead-only SIFNo~/.apptainer
Bottles/WineWindows appsWine prefixNo@home
Virtual MachinesFull hardware isolationComplete (own kernel)KVM group@libvirt
WaydroidAndroid appsLXC containerInit only@waydroid

Where Each Ecosystem Lives on Disk

Every ecosystem has its own Btrfs subvolume. None overlap. All survive OS updates and rollbacks because shani-deploy only writes to @blue or @green — never to these subvolumes.

Btrfs filesystem
├── @blue / @green     ← OS slots (only these change during shani-deploy)
├── @home              ← /home — your files, AppImages, Homebrew, Nix profile
├── @flatpak           ← /var/lib/flatpak
├── @snapd             ← /var/lib/snapd
├── @nix               ← /nix (shared across both OS slots)
├── @containers        ← /var/lib/containers (Distrobox + Podman)
├── @machines          ← /var/lib/machines (systemd-nspawn)
├── @lxc / @lxd        ← LXC and LXD containers
├── @libvirt / @qemu   ← VM disk images
└── @waydroid          ← /var/lib/waydroid

When to Use Each One

Flatpak — GUI applications (primary)

Flatpak is the right choice for almost every GUI desktop application. Flathub has thousands of apps — browsers, office suites, media players, creative tools, IDEs. Apps are sandboxed, auto-update every 12 hours, and their permissions are manageable via Flatseal (pre-installed).

flatpak install flathub org.mozilla.firefox
flatpak install flathub org.gimp.GIMP
flatpak install flathub com.spotify.Client
flatpak search "video editor"

Guide: Flatpak on Shani OS


Snap — GUI apps not on Flathub

Snap is pre-configured as a fallback when an app exists only on the Snap Store. snapd.socket is socket-activated — the daemon starts on demand. Snap packages live in @snapd.

snap install some-app
snap install code --classic
snap list

Guide: Snap on Shani OS


AppImage — portable / beta apps

AppImages are self-contained executables. Download, chmod +x, run. No installation, no system writes. Gear Lever (pre-installed on every edition) integrates them into your launcher and tracks updates.

chmod +x AppName.AppImage
./AppName.AppImage
# Or drag onto Gear Lever for launcher integration

Guide: AppImage on Shani OS


Nix — CLI tools and dev runtimes (primary)

Nix is pre-installed and the daemon is running. The @nix subvolume is shared between both OS slots — packages survive updates and rollbacks and are immediately available in the new slot. Over 100,000 packages. Multiple versions of the same tool coexist cleanly.

# Add a channel once (fresh install)
nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs
nix-channel --update

# Install anything
nix-env -iA nixpkgs.nodejs_22
nix-env -iA nixpkgs.rustup
nix-env -iA nixpkgs.ripgrep

Guide: Nix on Shani OS


Homebrew — if brew is muscle memory

Homebrew installs to /home/linuxbrew/.linuxbrew — completely outside the read-only OS root. Works identically to macOS. A reasonable choice for macOS switchers; Nix is more powerful for complex environments.

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
brew install ripgrep node jq

Guide: Homebrew on Shani OS


Distrobox — full mutable Linux environment

Distrobox creates a container of any Linux distribution — Arch, Ubuntu, Fedora — with that distro's full package manager intact. Your home directory is shared by default. Binaries and GUI apps can be exported to your host launcher. Containers live in @containers.

# Arch with AUR access
distrobox create --name arch-dev --image archlinux:latest
distrobox enter arch-dev
yay -S some-aur-package
distrobox-export --bin /usr/bin/some-tool

# Ubuntu with PPAs
distrobox create --name ubuntu-dev --image ubuntu:24.04
distrobox enter ubuntu-dev
sudo add-apt-repository ppa:some/ppa && sudo apt install some-package

Guide: Distrobox on Shani OS


Podman — services and databases

Podman is rootless, Docker-compatible, and daemon-free. Use it for persistent services: databases, web servers, self-hosted tools. The Pods app (pre-installed) gives you a graphical interface. podman-docker is pre-installed — existing docker commands work as-is.

podman run -d -p 5432:5432 -e POSTGRES_PASSWORD=secret postgres:16
podman run -d -p 6379:6379 redis:7-alpine
podman-compose up -d   # or docker compose up -d

Guide: Podman on Shani OS


Apptainer — HPC and cluster workloads

Apptainer (formerly Singularity) packages your entire environment into a single .sif file that runs identically on your Shani OS workstation and on any SLURM/PBS/LSF cluster. No root required. --nv and --rocm flags for GPU passthrough.

apptainer pull docker://pytorch/pytorch:latest
apptainer exec --nv pytorch_latest.sif python3 train.py
apptainer build --fakeroot myenv.sif myenv.def

Guide: Apptainer on Shani OS


LXC/LXD — full system containers

LXD runs complete Linux OS environments — init system, services, network stack — sharing the host kernel but fully isolated. Lighter than a VM, more complete than Distrobox. lxd.socket is socket-activated.

sudo lxd init --auto
lxc launch ubuntu:24.04 myserver
lxc exec myserver -- bash
lxc config device add myserver webport proxy listen=tcp:0.0.0.0:8080 connect=tcp:127.0.0.1:80

Guide: LXC and LXD on Shani OS


systemd-nspawn — lightweight system containers

systemd-nspawn is the lightest full-system container option. No daemon, no setup. Pull a tarball and boot it. Container filesystems live in @machines.

sudo machinectl pull-tar --verify=no \
  https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-basic.tar.zst archlinux
sudo machinectl start archlinux
sudo machinectl login archlinux

Guide: systemd-nspawn on Shani OS


Bottles/Wine — Windows applications

Bottles manages isolated Wine environments for running Windows .exe software directly on Linux. No Windows licence or VM required for most applications. Pre-installed on KDE Plasma, available on Flathub for GNOME.

flatpak install flathub com.usebottles.bottles
# Then: Bottles → Create bottle → Run Executable → select your .exe

Guide: Windows Apps on Shani OS


Virtual Machines — full hardware isolation

For software requiring a real Windows kernel, GPU passthrough, or a completely separate OS environment. virt-manager (pre-installed on KDE Plasma, org.virt_manager.virt-manager Flatpak on GNOME) uses QEMU/KVM for near-native performance. VM disks live in @libvirt.

Guide: Virtual Machines on Shani OS


Waydroid — Android apps

Waydroid runs a full hardware-accelerated Android stack in a container. Indian apps (BHIM, DigiLocker, IRCTC), streaming apps, and Android development testing all work natively on your desktop.

sudo waydroid init   # one-time setup
waydroid session start
waydroid show-full-ui
waydroid app install myapp.apk

Guide: Waydroid on Shani OS


Ecosystem Auto-Update Summary

EcosystemAuto-updates?How to manually update
FlatpakEvery 12 hours (systemd timer)flatpak update
SnapAutomatic (snapd daemon)snap refresh
AppImageVia Gear Lever (app-specific)Open Gear Lever
NixManualnix-channel --update && nix-env -u '*'
HomebrewManualbrew update && brew upgrade
DistroboxManual per-containerdistrobox enter name -- sudo apt upgrade
Podman imagesManualpodman pull image:latest
WaydroidVia OTA in Android UISettings → System → Software Update

The OS itself updates separately via shani-deploy and never interferes with any of the above.


Resources


Built in India 🇮🇳 · Immutable · Atomic · Zero Telemetry