320 lines
24 KiB
HTML
320 lines
24 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en-US">
|
|
<head>
|
|
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<meta name="generator" content="Norgolith" />
|
|
|
|
|
|
|
|
<meta name="description" content="I really like Nix" />
|
|
|
|
|
|
<meta name="author" content="Adumh00man" />
|
|
|
|
|
|
<meta name="keywords" content="linux, blog, nix" />
|
|
|
|
|
|
|
|
|
|
<meta property="og:title" content="Why Nixos Is The Coolest Operating System - Voidarc" />
|
|
<meta property="og:type" content="website" />
|
|
<meta property="og:url" content="https://blog.voidarc.co.uk/posts/nix/" />
|
|
<meta property="og:description" content="I really like Nix" />
|
|
<meta property="og:site_name" content="voidarc" />
|
|
<meta property="og:locale" content="en-US" />
|
|
|
|
<link rel="canonical" href="https://blog.voidarc.co.uk/posts/nix/" />
|
|
<meta name="robots" content="index, follow" />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="https://blog.voidarc.co.uk/assets/css/prism-sweetie.min.css" />
|
|
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
|
|
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
|
|
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/line-numbers/prism-line-numbers.min.js"></script>
|
|
|
|
|
|
|
|
|
|
<script defer src="https://cdn.jsdelivr.net/npm/@alpinejs/collapse@3.x.x/dist/cdn.min.js"></script>
|
|
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
|
<script>
|
|
document.addEventListener("alpine:init", () => {
|
|
Alpine.data("menu", () => ({
|
|
currentPage: window.location.pathname,
|
|
|
|
openMobile: false,
|
|
|
|
toggleMobile() {
|
|
this.openMobile = !this.openMobile;
|
|
}
|
|
}));
|
|
|
|
Alpine.data("toc", () => ({
|
|
open: false,
|
|
|
|
toggle() {
|
|
this.open = !this.open;
|
|
document.querySelector("#toc-toggle-icon").classList.toggle("rotate-90");
|
|
}
|
|
}));
|
|
|
|
Alpine.data("theme", () => ({
|
|
// Defaults to dark theme
|
|
current: "dark",
|
|
|
|
init() {
|
|
const storedTheme = localStorage.getItem("theme");
|
|
if (storedTheme === "dark") {
|
|
this.current = "dark";
|
|
} else if (storedTheme === "light") {
|
|
this.current = "light";
|
|
} else if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
this.current = "dark";
|
|
}
|
|
localStorage.setItem("theme", this.current);
|
|
if (this.current === "dark") {
|
|
document.documentElement.classList.add("dark");
|
|
}
|
|
},
|
|
|
|
toggle() {
|
|
this.current = this.current === "dark" ? "light" : "dark";
|
|
document.documentElement.classList.toggle("dark", this.current === "dark");
|
|
localStorage.setItem("theme", this.current);
|
|
}
|
|
}));
|
|
});
|
|
</script>
|
|
|
|
|
|
|
|
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/11.9.0/mermaid.min.js"></script>
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tabler-icons/3.28.1/tabler-icons.min.css">
|
|
|
|
|
|
<link rel="stylesheet" href="https://blog.voidarc.co.uk/assets/css/styles.min.css" />
|
|
|
|
<link rel="icon" href=/assets/norgolith.svg />
|
|
|
|
|
|
<title>Why Nixos Is The Coolest Operating System - Voidarc</title>
|
|
|
|
</head>
|
|
<body>
|
|
<div class="transition-colors duration-150 ease-linear">
|
|
<header class="relative shadow-sm">
|
|
<nav x-data="menu" class="container mx-auto px-4 md:px-0 font-mono">
|
|
<div class="flex items-center justify-between h-16">
|
|
<!-- Logo and dark mode -->
|
|
<div x-data="theme" class="flex items-center shrink-0 space-x-2">
|
|
<a href="https://blog.voidarc.co.uk/" class="flex items-center space-x-2">
|
|
<!-- <img src="https://blog.voidarc.co.uk/assets/norgolith.svg" alt="Norgolith Logo" class="h-8 w-8"> -->
|
|
<span class="text-lg md:text-xl font-bold text-magenta">Voidarc</span>
|
|
</a>
|
|
<button
|
|
@click="toggle()"
|
|
type="button"
|
|
class="rounded-lg flex items-center"
|
|
:aria-label="current === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'"
|
|
>
|
|
<i
|
|
:class="current === 'dark' ? 'ti-sun hover:text-yellow' : 'ti-moon hover:text-blue'"
|
|
class="ti text-xl md:text-2xl text-grey transition-colors duration-200 ease-in-out"
|
|
></i>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Desktop Menu -->
|
|
<div class="hidden md:flex md:items-center md:space-x-8">
|
|
|
|
<a
|
|
:class="{ 'text-magenta!': currentPage.startsWith('/posts') }"
|
|
class="text-text-alt hover:text-blue px-3 py-2 rounded-md text-sm font-medium"
|
|
href="https://blog.voidarc.co.uk/posts"
|
|
>Posts</a>
|
|
|
|
<a
|
|
:class="{ 'text-magenta!': currentPage.startsWith('/categories') }"
|
|
class="text-text-alt hover:text-blue px-3 py-2 rounded-md text-sm font-medium"
|
|
href="https://blog.voidarc.co.uk/categories"
|
|
>Tags</a>
|
|
|
|
</div>
|
|
|
|
<!-- Mobile Menu Button -->
|
|
<div class="md:hidden">
|
|
<button @click="toggleMobile" type="button" class="inline-flex items-center justify-center p-2 rounded-md text-dark-grey hover:text-text-alt focus:outline-none" aria-controls="mobile-menu" aria-expanded="false">
|
|
<span class="sr-only">Open main menu</span>
|
|
<!-- Hamburger Icon -->
|
|
<svg x-show="!openMobile" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
|
|
</svg>
|
|
<!-- Close Icon -->
|
|
<svg x-show="openMobile" class="h-5 w-5 text-red" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Mobile Menu -->
|
|
<div
|
|
x-show="openMobile"
|
|
x-transition:enter="transition ease-out duration-300"
|
|
x-transition:enter-start="opacity-0"
|
|
x-transition:enter-end="opacity-100"
|
|
x-transition:leave="transition ease-in duration-300"
|
|
x-transition:leave-start="opacity-100"
|
|
x-transition:leave-end="opacity-0"
|
|
@click.outside="openMobile = false"
|
|
class="md:hidden"
|
|
id="mobile-menu"
|
|
>
|
|
<div class="flex flex-row items-center justify-between pt-2 pb-4">
|
|
|
|
<a
|
|
:class="{ 'text-blue!': currentPage.startsWith('/posts') }"
|
|
class="text-text-alt hover:text-blue px-3 py-2 rounded-md text-sm font-medium"
|
|
href="https://blog.voidarc.co.uk/posts"
|
|
>Posts</a>
|
|
|
|
<a
|
|
:class="{ 'text-blue!': currentPage.startsWith('/categories') }"
|
|
class="text-text-alt hover:text-blue px-3 py-2 rounded-md text-sm font-medium"
|
|
href="https://blog.voidarc.co.uk/categories"
|
|
>Tags</a>
|
|
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
</header>
|
|
|
|
<main class="container mx-auto min-h-screen pt-8 px-4 md:px-0">
|
|
|
|
<div>
|
|
<h1>Why Nixos is the Coolest Operating System</h1>
|
|
</div>
|
|
<div class="flex flex-col md:flex-row">
|
|
<div class="flex flex-col md:flex-row flex-1 justify-between">
|
|
<div class="flex flex-col space-y-2">
|
|
|
|
|
|
|
|
<span class="text-grey text-sm tabular-nums text-opacity-70 dark:text-opacity-100 space-x-1">
|
|
<time datetime="2026-03-22T19:35:56+00:00">March 22, 2026</time>
|
|
|
|
</span>
|
|
</div>
|
|
|
|
<div class="flex flex-wrap items-center max-w-[50%]">
|
|
<span class="font-semibold mr-px">Tags: </span>
|
|
|
|
<a
|
|
class="w-fit bg-grey hover:bg-magenta text-base hover:text-base! no-underline! hover:no-underline! text-sm mr-2 last:mr-0 px-1 rounded-sm"
|
|
href="https://blog.voidarc.co.uk/categories/linux"
|
|
>
|
|
Linux
|
|
</a>
|
|
|
|
<a
|
|
class="w-fit bg-grey hover:bg-magenta text-base hover:text-base! no-underline! hover:no-underline! text-sm mr-2 last:mr-0 px-1 rounded-sm"
|
|
href="https://blog.voidarc.co.uk/categories/blog"
|
|
>
|
|
Blog
|
|
</a>
|
|
|
|
<a
|
|
class="w-fit bg-grey hover:bg-magenta text-base hover:text-base! no-underline! hover:no-underline! text-sm mr-2 last:mr-0 px-1 rounded-sm"
|
|
href="https://blog.voidarc.co.uk/categories/nix"
|
|
>
|
|
Nix
|
|
</a>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div x-data="toc" class="mt-4">
|
|
|
|
<button @click="toggle()" type="button" class="inline-flex items-center">
|
|
<span class="sr-only">Close Table of Contents</span>
|
|
<h3 class="mt-0! mr-1">
|
|
Table of Contents
|
|
</h3>
|
|
<span
|
|
id="toc-toggle-icon"
|
|
class="transition-all duration-300 ease-in-out text-2xl hover:text-blue ti ti-arrow-badge-right-filled"
|
|
></span>
|
|
</button>
|
|
<nav
|
|
x-transition:enter="transition ease-out duration-300"
|
|
x-transition:enter-start="opacity-0"
|
|
x-transition:enter-end="opacity-100"
|
|
x-transition:leave="transition ease-in duration-300"
|
|
x-transition:leave-start="opacity-100"
|
|
x-transition:leave-end="opacity-0"
|
|
x-show="open"
|
|
class="toc"
|
|
>
|
|
<ol><li><a href="#The-Nixos-Philosophy">The Nixos Philosophy</a><ol><li><a href="#Origins">Origins</a></li><li><a href="#Reasoning-and-Methodology">Reasoning and Methodology</a><ol><li><a href="#The-AUR">The AUR</a></li><li><a href="#Nixpkgs">Nixpkgs</a></li></ol></li><li><a href="#In-practice">In practice</a></li><li><a href="#Nixos,-the-coolest-operating-system">Nixos, the coolest operating system</a></li><li><a href="#Home-Manager:-An-attempt-was-made">Home Manager: An attempt was made</a></li><li><a href="#The-Better-way-to-manage-dotfiles">The Better way to manage dotfiles</a></li><li><a href="#Doot:-The-Fast,-Intuitive-dotfiles-manager">Doot: The Fast, Intuitive dotfiles manager</a></li><li><a href="#What-was-I-talking-about-again?">What was I talking about again?</a></li><li><a href="#Moral-of-the-story-(or-something)">Moral of the story (or something)</a></li></ol></li></ol>
|
|
</nav>
|
|
</div>
|
|
|
|
<div id="content" class="mt-12 break-keep pt-10 border-t border-t-base-alt dark:border-t-[#39394b]">
|
|
<h1 id="The-Nixos-Philosophy" >The Nixos Philosophy</h1> <p >Nix is the all in one solution to every problem you could have with Linux. It prides itself on being a fully declarative way to install and manage system packages, and It (mostly) achieves those goals. Before trying to involve oneself in such matters, though, an important distinction to make is that Nix as a concept, and a package manager, is seperate from Nixos as a system. Nix can, and should, in some cases, exist outside of Nixos. But, let's get onto that later.</p><h2 id="Origins" >Origins</h2> <p >If you wanted a full rundown on how nix came about, then you're in the wrong place. Go read wikipedia or something. The main thing that you need to know is that the nix language, and therefore the packaging system, was made on a whim for a university dissertation. First of all, that's pretty insane. Making an entire programming language for the sake of it, and I wouldn't even be surprised if he didn't get full credit. It quickly caught the attention of all the linux nerds out there, and before long it had evolved into the nix project that we know and love today.</p><h2 id="Reasoning-and-Methodology" >Reasoning and Methodology</h2> <p >The main draw of nix as a concept is it's reproducability. It works similarly, and often in tandem with, Git. The git working tree is a simple concept. A long ledger of changes (more commonly called diffs), that when put together results in a full codebase. Nix uses this principle to its advantage, and I will demonstrate this by comparing nixpkgs with another common package repo, the AUR.</p><h3 id="The-AUR" >The AUR</h3> <p >The AUR is the Arch User Repository, a gigantic collection of packages uploaded by anyone that can be asked to figure out how PKGBUILDS work. PKGBUILDS are a form of makefile, that is used as a standard way of declaring dependancies, versions wherein, and how to build a given app. These PKGBUILDS are stored within the repos they are associated with, and are therefore versioned alongside the app. When you upload an app to the AUR, and it is approved, a static version of your app, ie one commit, is hosted on the aur domain. This url is read only, and cannot be viewed like something hosted on github. To install the app, you clone the repo and use <code>makepkg -si</code> to compile.</p><p >The key part of all of that is that only one commit is hosted at a time. Because arch is a "rolling release" distro, they see no need to waste storage on older versions of apps. This is an issue, when there is a breaking change and you cannot roll back to an older version of a package, because it no longer exists. This is remedied slightly by the pacman cache, but that only goes for your local machine. If you need a specific version of an app, then either compile from source or give up.</p><p >But, I hear you ask, what happened to git versioning? Can't you just roll back to an older commit and use the PKGBUILD from there? This, my friend, is where Nix comes in.</p><h3 id="Nixpkgs" >Nixpkgs</h3> <p >Nixpkgs is, without exxageration, a git repository. Every time you install a package, the entire repo is pulled to your local machine. Despite the fact that, at the time of writing, it has over 200,000 packages, it is still small enough, because of how diffs work, to be downloaded every time you need to update an app. The reason for this is that it leverages git histories to their maximum potential.</p><p >Git, as I said, is just a long ledger of changes. All diffs are stored in the .git folder, along with some other stuff that might be important to someone someday. Every time you make a commit, a new hash is generated. It isn't important how the hash is generated, just that every commit has a unique hash associated with it. This gives rise to revisions. With this hash, you can address a specific state of the ecode at that commit, and this is what nix uses to stay so small.</p><p >Every package has a .nix file, that details its build process. This can be as simple as compiling one file to a binary, all the way up to compiling the whole linux kernel. Nix in of itself is a wrapper for every other build system, which means that any app that can be built can be run on nix. Hence, when enough apps are compiled, nixpkgs becomes completely self sufficient. For an app to be built with nix, all of its dependancies, and the builder itself, must also be built with nix. This means that, instead of using a manner of different build systems, and rolling release nonsense, that means that you can never be sure if you're getting the same version of a dependancy an app was developed with, you simply call another nix file, at a specific rev, or commit.</p><p >This leads to what is known as a dependancy chain. Because you call every dependancy with a specific rev, you can make sure that you are getting the right version. When you get down to the actual source code, that isn't nix, you download the specified rev of the third party repo, and compile that. If an app compiles once, it will always compile, because the git ledger should never be changed manually.</p><h2 id="In-practice" >In practice</h2> <p >Due to the existence of flakes, something that I'll get to later, this is made much easier. No more "it works on my machine", because, for all intents and purposes, all machines are identical when running nix. There are no outside dependancies, so there is no way for an app to fail to compile. Nix as a package manager can be used on other systems, being monolithically configured with one file, that can be shared and rebuilt on any other machine with (almost) exactly the same functionality.</p><p >Hang on, this sounds awfully familiar. Like a problem that system integrators have been trying to solve for years, but could only come so close. And so, the quest for a system built with Nix began.</p><h2 id="Nixos,-the-coolest-operating-system" >Nixos, the coolest operating system</h2> <p >Nixos is what came of that endeavour. A system fully defined by code. A system that could be rebuilt over and over, with exactly the same result, on multiple machines. This had the added benefit of the same git methodology that nixpkgs was based on. No more updates that rendered your computer unusable! You could simply revert back to a previous revision of your system, using the same diff structure that git uses, but with boot entries and packages instead of just code.</p><p >Nixos is the pinnacle of stability. By definition, there can't be a more stable system. By virtue of the fact that It can be rolled back, it cannot be defeated in that regard. It is impossible to have conflicting packages, because, in theory, all packages can be installed alongside eachother. If you want to install 50 different versions of the linux kernel at once, then go ahead! If you want to run 10 different versions of firefox on the same machine, there's nothing stopping you! You get all of the benefits of rolling release, while also having the option of installing a 5 year old version of onlyoffice in the same breath.</p><p >And the best part? Your system config, in of itself, can be controlled by git! It's git all the way down! I can instantly have the same system I did 6 months ago if I wanted to, the only difference being the user files, of course. Ah, the user files.</p><h2 id="Home-Manager:-An-attempt-was-made" >Home Manager: An attempt was made</h2> <p >Home manager is the logical extension of Nixos. A way to control dotfiles, or really any file, through nix. Revisions, versioning, etc. It seems like a good idea on paper, until you try to use it.</p><p >First of all, the way that home manager works is exactly the same as the nix store. It creates a load of read only folders, and then generates the immutable config files within. Seems reasonable, why would you want to change them in the first place? Two words: Lock File. Nvim is the main culprit when it comes to issues like this. The Lazy.lock file can't update, because presumably the entire <code>.config/nvim</code> folder was created by home-manager, meaning that updating packages is nearly impossible. All home manager leads to is a massive headache at the end of the day. Especially when you come across some unsupported app, where you have to paste in the non-nix config so that home-manager can copy and paste it into a read only file somewhere else in your home directory.</p><p >Because of these issues, I have taken a different approach, which I will now go on a tangent about.</p><h2 id="The-Better-way-to-manage-dotfiles" >The Better way to manage dotfiles</h2> <p >Stow is an old GNU utility. It calls itself a "symlink farm", which is fancy speak for "it takes files in a directory and links them to another place". The idea is that you have a folder with all of your dotfiles in, the ones that you actually care about, and stow links them to your actual .config directory. I used this for a while, in order to manage my hyprland and nvim configs more nicely.</p><p >Due to the fact it's a GNU utility, however, it's really old. And doesn't have nice features. It was never intended to be a dotfiles manager, so didn't have the killer feature that I would need to make a proper nix config. Multiple host support.</p><p >I have 2 machines that I have nix on. My laptop and my desktop. I want a similar experience between the two, but some things I want to be different. Nixos thought of this, and made it so that you could have different outputs in a flake, that represented different systems. But what about all my other nonsense? My monitor names are different between the two machines, and I had different keyboard styles, so wanted different modifiers too! This could be remedied by loads of scripts, but that was boring. I needed something new. Something... Intuitive.</p><h2 id="Doot:-The-Fast,-Intuitive-dotfiles-manager" >Doot: The Fast, Intuitive dotfiles manager</h2> <p ><a href="https://github.com/pol-rivero/doot" >Doot</a> is my choice for a dotfiles manager. It's fast(ish), configurable, and, most importantly, was built with multiple hosts in mind. If you want to see how it works more closeley, click the link at the start of this paragraph, or have a look at my <a href="https://git.voidarc.co.uk/voidarc/config" >Dotfiles</a>, which I think are pretty cool. For those of you that can't be asked to have a look, though, I'll explain the concept as simply as I can be bothered.</p><p >Your doot repo is located in the <code>.dotfiles</code> directory, next to .config. When you run <code>doot install</code>, the folders in your repo are mapped to your home directory in the same structure as they were in the repo. Eg, if you put a .zshrc in the root of the repo, it will end up in the right place. So far, this is exactly the same as stow, the only difference being where stow would link a whole folder, doot creates the structure in place and only symlinks files.</p><p >Doot can be configured in the doot folder, in the root of the repo, that will not be mapped to the home directory. The doot config contains things like exclude files (like .gitignores and licences), the diff viewer you want to use to see file changes, and your different hosts. Doot manages hosts intelligently, using the hostname of the machine as an indicator. Here is my host config:</p><pre ><code class="language-toml">[hosts]
|
|
"HACKSTATION" = "pc-files"
|
|
"mobile02" = "laptop-files"
|
|
</code></pre><p >The keys on the right correspond to the different hostnames, and the keys on the right correspond to the folders that contain the dotfiles specific to that machine. These folders are located in the root of the repo, and within them, contain another structure that is relative to your home directory. Eg, in the pc-files directory, there is also a <code>.config</code> directory, with some specific hyprland configs that only work on my PC.</p><h2 id="What-was-I-talking-about-again?" >What was I talking about again?</h2> <p >You could, of course, version every single file on your disk using this method, but that sounds like a waste of time. There will never be a world where 100% of a system is always generated by nix, because there will always be some random app that only compiles to an appimage and uses proprietary config locations or something. Nevermind how you would manage something like a download folder.</p><p >I believe that Nix, and Nixpkgs, is the gold standard when it comes to software development. There are genuine, real world uses for stuff like this. Sites like replit are fully managed and distributed using nix, because of how stupidly stable it is. You can define whole Kubernetes clusters on nix, and then update them in place with 0 downtime. Pretty impressive. However, as tends to happen with nerds on the internet (me included), the concept and utility that comes along with something like nix is buried under who can make the lightest or best looking config.</p><h2 id="Moral-of-the-story-(or-something)" >Moral of the story (or something)</h2> <p >Nix isn't for everyone. If you don't care about versioning everything in your entire life, then you're probably better off sticking with something like arch. If you don't mind that you have slightly different configs across different machines, then there's no need for you to learn how to use flakes so that you can make sure that you have identical packages on all of your systems.</p><p >But, It sure is fun to mess around with. If you're on the fence about trying nix, then this is your indicator to switch. It will make you feel a great deal of things, but regret will not be one of those feelings.</p>
|
|
</div>
|
|
|
|
</main>
|
|
|
|
<footer class="mt-8 py-4 px-6 w-full font-mono">
|
|
<div
|
|
class="flex flex-col md:flex-row justify-between md:items-center font-medium text-xs md:text-sm text-text-alt space-y-4 md:space-y-0"
|
|
>
|
|
<span
|
|
>Copyright © 2026
|
|
|
|
<a
|
|
href="https://git.voidarc.co.uk/voidarc"
|
|
class="text-blue hover:underline">Adumh00man</a
|
|
>.
|
|
|
|
|
|
<br class="md:hidden" /> Licensed under MIT.
|
|
|
|
</span>
|
|
<div class="flex flex-inline">
|
|
|
|
<div class="mr-4 md:mr-6 lg:mr-8 last:mr-0">
|
|
<a
|
|
href="https://git.voidarc.co.uk/voidarc"
|
|
class="hover:text-blue"
|
|
>
|
|
<span>Git</span>
|
|
</a>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</footer>
|
|
</div>
|
|
</body>
|
|
</html>
|