Migrating to Shani OS from Ubuntu, Fedora, or Arch — A Practical Guide

The most common question from experienced Linux users considering Shani OS is: "I know how to manage a system with pacman/apt/dnf. What do I actually do differently here?"

The honest answer is: not much changes in daily use. You still install apps, manage services, configure your system, and run development tools. The difference is that each category of software has a specific layer it belongs to — and once you understand the three-layer model, the new habits are straightforward.

This guide is a direct translation guide. Every traditional workflow maps to a Shani OS equivalent. Full reference: docs.shani.dev.


The Mental Model Shift

On a traditional Linux distribution, software installation means writing files into the OS root. The package manager is the single source of truth for what is installed. You manage everything — system libraries, GUI apps, CLI tools, development runtimes — through the same tool.

On Shani OS, the OS root is frozen. It is a verified, signed image. You do not write into it because doing so would undermine the entire reliability guarantee: if you can add arbitrary packages to the OS, the OS is no longer the reproducible artefact that the update pipeline verified.

Instead, persistent layers sit alongside the OS, each in its own Btrfs subvolume:

  1. @flatpak — GUI desktop applications (browsers, office, media, etc.)
  2. @snapd — Snap packages when an app is only available on the Snap Store
  3. @nix — CLI tools, development runtimes, and language toolchains
  4. @containers — Distrobox and Podman OCI containers
  5. @machines — systemd-nspawn system containers
  6. @lxc / @lxd — LXC/LXD full system containers
  7. @libvirt / @qemu — Virtual machine disk images
  8. @waydroid — Android environment

All survive every OS update and rollback. They are never touched by shani-deploy. They have their own update paths. They do not conflict with each other.


Package Installation: The Full Translation Table

GUI Applications

TraditionalShani OS
sudo apt install firefoxflatpak install flathub org.mozilla.firefox
sudo dnf install gimpflatpak install flathub org.gimp.GIMP
sudo pacman -S vlcflatpak install flathub org.videolan.VLC
yay -S spotifyflatpak install flathub com.spotify.Client
sudo apt install codeflatpak install flathub com.visualstudio.code

Search for the Flatpak app ID at flathub.org or via flatpak search <n>. Most major GUI applications are on Flathub. If an app is only available on the Snap Store, snap install <n> works as a fallback — Snap is pre-configured on Shani OS and the @snapd subvolume persists across updates just like @flatpak.

Windows Applications

Windows .exe software runs through Wine — a compatibility layer that translates Windows API calls to Linux equivalents. No Windows licence required, no VM overhead for most apps.

TraditionalShani OS
Run a Windows .exe installerOpen with Bottles — creates an isolated Wine environment
Install a Windows productivity toolBottles → Create bottle → Run Executable
Run legacy Windows softwareBottles with Wine Staging or Wine-GE runner
Windows game (non-Steam)Bottles with Wine-GE, or Heroic Games Launcher

Bottles (com.usebottles.bottles) is pre-installed on the KDE Plasma edition and available on Flathub for the GNOME edition. It manages isolated Wine prefixes per application, handles runtime dependencies (Visual C++, .NET, DirectX) via its built-in dependency installer, and supports multiple Wine runners including Wine-GE and Proton-GE.

For applications that require a real Windows kernel — hardware drivers, anti-cheat systems, enterprise software with kernel-level components — a Windows VM via virt-manager (pre-installed on KDE Plasma) or GNOME Boxes is the reliable path. VM disk images live in @libvirt, completely independent of the OS. Guide: Windows Apps on Shani OS · Virtual Machines on Shani OS.

For portable self-contained tools distributed as AppImages, download the .AppImage, make it executable, and run — or open with Gear Lever (pre-installed) to add it permanently to your launcher with automatic update checking.

CLI Tools and Development Runtimes

TraditionalShani OS
sudo apt install nodejsnix-env -iA nixpkgs.nodejs
sudo pacman -S pythonnix-env -iA nixpkgs.python312
sudo dnf install rustupnix-env -iA nixpkgs.rustup
sudo apt install ripgrepnix-env -iA nixpkgs.ripgrep
sudo pacman -S kubectlnix-env -iA nixpkgs.kubectl
brew install batnix-env -iA nixpkgs.bat
sudo apt install golangnix-env -iA nixpkgs.go
sudo pacman -S neovimnix-env -iA nixpkgs.neovim

Before using Nix, add a channel once:

nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs
nix-channel --update

Then install anything from the 100,000+ packages at search.nixos.org:

nix-env -iA nixpkgs.package-name

System-Level Software (Not Available)

Some categories of software cannot be installed into the OS root and must use alternatives:

TraditionalShani OS Alternative
sudo pacman -S nvidiaDrivers are part of the OS image; already configured at install
sudo apt install linux-headersKernel headers are in the OS image
Kernel modules via DKMSCustom modules are not supported; use upstream drivers
sudo apt install dockerUse Podman (pre-installed, Docker-compatible)

This is a short list. Most software that experienced Linux users install falls into the GUI apps or CLI tools categories above, both of which have direct equivalents.


System Management

System Updates

TraditionalShani OS
sudo apt upgradesudo shani-deploy
sudo pacman -Syusudo shani-deploy
sudo dnf upgradesudo shani-deploy
Reboot to apply kernelReboot after shani-deploy
Roll back to previous packagessudo shani-deploy -r (entire OS, instant)

The critical difference: shani-deploy replaces the entire OS image, not individual packages. There is no "partial update" state. Either the update applies fully and cleanly, or it does not apply at all. And if the new image causes problems, rollback takes you back to the previous complete OS state — not a partial undo.

Service Management

Service management with systemctl works identically:

# All standard systemctl commands work
sudo systemctl enable sshd
sudo systemctl start nginx
sudo systemctl status nginx
sudo systemctl restart NetworkManager

# Enabling services persists via the /etc OverlayFS
# Your enabled services survive OS updates

Configuration Files

Editing /etc files works exactly as expected. Changes are stored in the OverlayFS upper layer (@data) and persist across every OS update and rollback:

# Edit any /etc file normally
sudo nano /etc/ssh/sshd_config
sudo nano /etc/hostname
sudo nano /etc/hosts

# Changes to /etc persist — they are yours across updates

To see what you have customised (what differs from the OS defaults):

ls /data/overlay/etc/upper/

If an /etc change causes a problem, you can revert a specific file to the OS default:

sudo rm /data/overlay/etc/upper/path/to/file
# The OS default (lower OverlayFS layer) becomes active again

Development Workflows

Multiple Versions of the Same Tool

One of the most common pain points on traditional distributions: needing Node 18 for one project and Node 22 for another. Package managers typically only have one version of a tool installed at a time.

Nix solves this cleanly:

# Install both versions simultaneously — no conflict
nix-env -iA nixpkgs.nodejs_18
nix-env -iA nixpkgs.nodejs_22

# Per-project shell with a specific version (does not install globally)
nix-shell -p nodejs_18  # enters a shell with Node 18 on PATH
nix-shell -p nodejs_22  # separate shell with Node 22

# Reproducible project environment via shell.nix
# Place in project root — everyone running nix-shell gets identical tools

Full Nix guide: Nix on Shani OS.

Full System Containers (LXC/LXD and systemd-nspawn)

For workflows that need a complete isolated Linux system — with its own init, services, and network stack, lighter than a full VM — two options are pre-installed:

LXC/LXD is the more full-featured option, with a built-in image catalog, port forwarding, and snapshot management. Container storage lives in @lxc/@lxd:

lxc launch ubuntu:24.04 myserver
lxc exec myserver -- bash

systemd-nspawn is the lightest option — no daemon, no image format, just point it at a Linux root directory and it boots. 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

Android Apps and Development

Waydroid runs a full hardware-accelerated Android stack in a container. Indian apps (BHIM, DigiLocker, IRCTC), streaming apps, and Android development testing all work without a separate device. The @waydroid subvolume persists across every OS update:

sudo waydroid init    # one-time setup
waydroid session start
waydroid show-full-ui
waydroid app install myapp.apk    # test your APK with adb

Guide: Waydroid on Shani OS.

The AUR is not directly available on Shani OS — but the full Arch Linux experience, including yay and the AUR, is one command away via Distrobox:

# Create a full Arch Linux container with AUR access
distrobox create --name arch --image archlinux:latest
distrobox enter arch

# Inside: full pacman, yay, makepkg — everything works
yay -S some-aur-package

# Export a binary to your host desktop
distrobox-export --bin /usr/bin/some-tool

Exported binaries from Distrobox containers appear in your host PATH and app launcher. BoxBuddy (pre-installed) gives you a graphical interface for creating and entering containers.

PPAs and Third-Party Repos (Ubuntu Users)

Third-party APT repos and PPAs are not available for the host OS, but the same approach works inside a Distrobox Ubuntu container:

distrobox create --name ubuntu-dev --image ubuntu:24.04
distrobox enter ubuntu-dev

# Inside: standard apt, add-apt-repository, PPAs — all work
sudo add-apt-repository ppa:some/ppa
sudo apt install some-package
distrobox-export --bin /usr/bin/some-package

Filesystem Layout: What Changed

The parts of the filesystem you regularly interact with are the same. The OS root directories have different behaviour:

DirectoryBehaviour
/homeFully writable, stored in @home — unchanged from any Linux distro
/etcWritable via OverlayFS — your changes persist
/tmpWritable tmpfs — cleared on reboot as usual
/usrRead-only — OS files live here, you cannot modify them
/bin, /lib, /sbinSymlinks into /usr — effectively read-only
/vartmpfs — cleared on reboot; persistent state bind-mounted from @data
/nixWritable by Nix — your Nix packages live here (@nix)
/var/lib/flatpakFlatpak apps — writable via @flatpak
/var/lib/snapdSnap packages — writable via @snapd
/var/lib/containersDistrobox and Podman containers — writable via @containers
/var/lib/machinessystemd-nspawn system containers — writable via @machines
/var/lib/lxdLXD containers — writable via @lxd
/var/lib/libvirtVM disk images — writable via @libvirt
/var/lib/waydroidAndroid environment — writable via @waydroid

The read-only nature of /usr is the main thing to internalise. Anything that tries to write to /usr/local/bin or install files into /usr/share will fail. Use Nix, Flatpak, Snap, or Distrobox instead.


Shell and Terminal Experience

The shell environment is configured out of the box with the tools experienced Linux users expect:

# Already installed and configured
echo $SHELL         # /usr/bin/zsh
which starship      # /usr/bin/starship (prompt)
which fzf           # /usr/bin/fzf (fuzzy finder)
which bat           # already in PATH (Nix or system)
which eza           # modern ls replacement

# McFly for smart command history (replaces Ctrl+R)
# Already integrated into the shell config

Your .zshrc and .bashrc in $HOME work exactly as expected. Shell configuration is in your home directory (@home), completely independent of the OS.


Backup and Data Management

Before migrating, back up your existing system's data. After migrating, your home directory is your primary concern — the OS can always be reinstalled or rolled back, but your data lives in @home.

# restic is pre-installed — encrypted, versioned backups
restic -r s3:s3.amazonaws.com/mybucket init
restic -r s3:s3.amazonaws.com/mybucket backup ~/Documents ~/Projects ~/Pictures

# rclone is pre-installed — sync to cloud storage
rclone config  # set up Google Drive, S3, Backblaze, etc.
rclone sync ~/Documents gdrive:Backup/Documents

Both restic and rclone configurations persist in /data/varlib/ and survive OS updates.


The Things That Just Work

These do not require any migration thought — they work on Shani OS exactly as they do on any Linux distribution:

  • SSH, GPG keys, and credential management (stored in ~/.ssh and ~/.gnupg)
  • Docker Compose workflows (use podman compose or podman-docker drop-in)
  • Git repositories and configuration
  • Terminal emulators, Tmux, and screen sessions
  • Python virtual environments in ~/.venv or project directories
  • Node projects in ~/projects with node_modules
  • Dotfiles managed by stow, chezmoi, or a bare git repo
  • Any tool or script that lives in your home directory

Resources

Download Shani OS at shani.dev →


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