<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Configuration on Jon Seager</title><link>https://jnsgr.uk/tags/configuration/</link><description>Recent content in Configuration on Jon Seager</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Tue, 24 Jun 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://jnsgr.uk/tags/configuration/index.xml" rel="self" type="application/rss+xml"/><item><title>From NixOS to Ubuntu</title><link>https://jnsgr.uk/2025/06/from-nixos-to-ubuntu/</link><pubDate>Tue, 24 Jun 2025 00:00:00 +0000</pubDate><guid>https://jnsgr.uk/2025/06/from-nixos-to-ubuntu/</guid><description>&lt;p&gt;Following my appointment as VP Engineering for Ubuntu, I moved all of my machines from NixOS to Ubuntu. Being responsible for decisions that affect millions of Ubuntu users comes with, in my opinion, the obligation to &lt;em&gt;use&lt;/em&gt; the product and live with those decisions myself.&lt;/p&gt;
&lt;p&gt;Following years of running Arch Linux and NixOS, I imagined this would be uncomfortable, but was pleasantly surprised. In this post, I&amp;rsquo;ll outline my setup and a new philosophy for how I configure my machines.&lt;/p&gt;
&lt;p&gt;Last year, I wrote &lt;a href="https://jnsgr.uk/2024/07/how-i-computer-in-2024/" target="_blank" rel="noreferrer"&gt;in detail&lt;/a&gt; about my setup. Consider this post a &amp;ldquo;diff&amp;rdquo; on what&amp;rsquo;s changed since.&lt;/p&gt;
&lt;h2 id="recap-why-nixos" class="relative group"&gt;Recap: Why NixOS? &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#recap-why-nixos" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;NixOS affords a seemingly endless selection of applications, desktop environments and when combined with &lt;a href="https://github.com/nix-community/home-manager" target="_blank" rel="noreferrer"&gt;Home Manager&lt;/a&gt; it provides a consistent way to manage the configuration of almost all aspects of a system.&lt;/p&gt;
&lt;p&gt;People have argued that this is overkill, and results in needlessly complex configurations that produce difficult to read error messages, and make a system more difficult to troubleshoot.&lt;/p&gt;
&lt;p&gt;While I had some troubles adopting NixOS, I consistently felt that the positives outweighed the negatives: I loved being able to overlay individual packages and tweak fundamentals of the system in a machine specific way. I also liked being able to trivially reuse configuration for app and hardware configuration across my machines in a single &lt;a href="https://github.com/jnsgruk/nixos-config" target="_blank" rel="noreferrer"&gt;flake&lt;/a&gt;, which remains (to my amazement) one of my most popular GitHub repositories.&lt;/p&gt;
&lt;p&gt;As I planned my move to Ubuntu, I decided to change the way I used my computer to avoid fighting my machine, and any feeling that I could be missing out on the &lt;del&gt;complexity&lt;/del&gt; flexibility I&amp;rsquo;d become so used to.&lt;/p&gt;
&lt;h2 id="adopting-jfui" class="relative group"&gt;Adopting &amp;ldquo;JFUI&amp;rdquo; &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#adopting-jfui" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;The guiding principle for my new way of thinking is &lt;strong&gt;JFUI: Just F*cking Use It&lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;The primary motivation behind JFUI is to pick applications for which the defaults are close enough to my preferences, then use them with as little (or no) configuration as possible.&lt;/p&gt;
&lt;p&gt;By employing this principle, I should spend less of my time updating my configuration files as things change, and spend less time obsessing over every last theme detail for each application on my machine.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve spent years collecting &lt;a href="https://github.com/jnsgruk/dotfiles" target="_blank" rel="noreferrer"&gt;repositories full of dotfiles&lt;/a&gt;, which contains the ~2500 lines of configuration and scripts I used prior to moving to NixOS. As of today, the most recent commit in &lt;a href="https://github.com/jnsgruk/nixos-config" target="_blank" rel="noreferrer"&gt;my Nix flake&lt;/a&gt;, &lt;code&gt;cloc&lt;/code&gt; reports:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;---------------------------------------------------
Language files blank comment code
---------------------------------------------------
Nix 113 401 232 3666
Bourne Again Shell 3 25 30 95
Bourne Shell 1 17 0 83
Markdown 1 19 1 81
YAML 4 8 3 51
diff 1 1 7 6
---------------------------------------------------
SUM: 123 471 273 3982
---------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And that seems like &lt;em&gt;a lot&lt;/em&gt; to me! Yet this number omits my Visual Studio Code configuration (a further 200 lines of JSON), various browser configurations, etc.&lt;/p&gt;
&lt;p&gt;So I challenged myself to set up my Ubuntu machines with as little configuration as possible and to choose apps with better defaults.&lt;/p&gt;
&lt;h2 id="desktop-environment" class="relative group"&gt;Desktop Environment &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#desktop-environment" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;It&amp;rsquo;d been a long time since I&amp;rsquo;d used a computer regularly without a tiling window manager. I switched to &lt;a href="https://swaywm.org/" target="_blank" rel="noreferrer"&gt;sway&lt;/a&gt; in 2019, and to &lt;a href="https://hypr.land/" target="_blank" rel="noreferrer"&gt;Hyprland&lt;/a&gt; in 2023.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve built a lot of muscle memory by using a consistent keymap across both environments. I &lt;a href="https://jnsgr.uk/2024/07/how-i-computer-in-2024/" target="_blank" rel="noreferrer"&gt;use&lt;/a&gt; a 57&amp;quot; ultrawide monitor, and the idea of using it &lt;em&gt;without tiling&lt;/em&gt; seemed like total anarchy to me.&lt;/p&gt;
&lt;p&gt;But it didn&amp;rsquo;t take me long to adapt to using GNOME again. Despite abstaining from it for years, I&amp;rsquo;ve always appreciated the visual design of GNOME and often used their apps as part of my tiling experience (&lt;a href="https://apps.gnome.org/en-GB/Nautilus/" target="_blank" rel="noreferrer"&gt;Files&lt;/a&gt;, &lt;a href="https://apps.gnome.org/en-GB/Papers/" target="_blank" rel="noreferrer"&gt;Papers&lt;/a&gt;, &lt;a href="https://apps.gnome.org/en-GB/Loupe/" target="_blank" rel="noreferrer"&gt;Loupe&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Features such as the keyring, light/dark mode switching worked for me under Sway/Hyprland, but it always required complex, fragile configuration. The out of the box experience for configuring WiFi networks and Bluetooth devices feels modern, and like a part of the OS, rather than a kit of parts. In my latter few months of running Hyprland, I struggled more with consistent theming and stability as Hyprland evolved separately from the themes and apps I liked.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t attribute any blame for this; it&amp;rsquo;s a natural side effect of combining lots of independent and often complex parts from across the Linux desktop ecosystem, and I was consciously running pre 1.0 software knowing there would be issues because I enjoyed the overall experience.&lt;/p&gt;
&lt;h3 id="gnome-extensions" class="relative group"&gt;GNOME Extensions &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#gnome-extensions" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h3&gt;&lt;p&gt;This is the area where I violated JFUI the most, though some of it is temporary as I get further away from my existing workflow. I disable the Ubuntu dock, desktop icons, app indicators and Ubuntu tiling assistant. While the tiling assistant was a great step up on what came before it, it fell short of what I needed to manage windows on my large display.&lt;/p&gt;
&lt;p&gt;I took inspiration from &lt;a href="https://omakub.org/" target="_blank" rel="noreferrer"&gt;Omakub&lt;/a&gt;, which is where I discovered &lt;a href="https://extensions.gnome.org/extension/4548/tactile/" target="_blank" rel="noreferrer"&gt;Tactile&lt;/a&gt; - a GNOME extension for tiling windows to a custom on-screen grid using the keyboard. I&amp;rsquo;ve found this to be invaluable, and easily the best window management experience for GNOME. I&amp;rsquo;ve customised the grid to the following ratios (using &lt;code&gt;gsettings&lt;/code&gt; in a script):&lt;/p&gt;
&lt;p&gt;&lt;a href="01.png"&gt;
&lt;figure&gt;
&lt;picture
class="mx-auto my-0 rounded-md"
&gt;
&lt;source
srcset="https://jnsgr.uk/2025/06/from-nixos-to-ubuntu/01_hu_563a2ca534804b07.webp 330w,https://jnsgr.uk/2025/06/from-nixos-to-ubuntu/01_hu_a88883170768e81a.webp 660w
,https://jnsgr.uk/2025/06/from-nixos-to-ubuntu/01_hu_f9d64651fdeef908.webp 959w
,https://jnsgr.uk/2025/06/from-nixos-to-ubuntu/01_hu_f9d64651fdeef908.webp 959w
"
sizes="100vw"
type="image/webp"
/&gt;
&lt;img
width="959"
height="522"
class="mx-auto my-0 rounded-md"
alt="a screenshot of the tactile gnome extension configuration window"
loading="lazy" decoding="async"
src="https://jnsgr.uk/2025/06/from-nixos-to-ubuntu/01_hu_d63430834ff566c4.png" srcset="https://jnsgr.uk/2025/06/from-nixos-to-ubuntu/01_hu_ebdaf981cf8217b8.png 330w,https://jnsgr.uk/2025/06/from-nixos-to-ubuntu/01_hu_d63430834ff566c4.png 660w
,https://jnsgr.uk/2025/06/from-nixos-to-ubuntu/01.png 959w
,https://jnsgr.uk/2025/06/from-nixos-to-ubuntu/01.png 959w
"
sizes="100vw"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve grown to like &lt;a href="https://extensions.gnome.org/extension/5090/space-bar/" target="_blank" rel="noreferrer"&gt;Space Bar&lt;/a&gt; - it provides desktop workspaces akin to those in Sway/Hyprland which enabled me to use the muscle memory I&amp;rsquo;d developed over years. As I&amp;rsquo;ve progressed, I think I &lt;em&gt;could&lt;/em&gt; live without Space Bar and use the native workspace features in GNOME, so I&amp;rsquo;ll experiment with that soon.&lt;/p&gt;
&lt;p&gt;The final two are somewhat simpler: &lt;a href="https://extensions.gnome.org/extension/6242/emoji-copy/" target="_blank" rel="noreferrer"&gt;Emoji Copy&lt;/a&gt; (mapped to &lt;code&gt;Super + E&lt;/code&gt;) and &lt;a href="https://extensions.gnome.org/extension/4839/clipboard-history/" target="_blank" rel="noreferrer"&gt;Clipboard History&lt;/a&gt; (mapped to &lt;code&gt;Super + V&lt;/code&gt;), functions that were previously enabled by &lt;a href="https://github.com/SimplyCEO/wofi" target="_blank" rel="noreferrer"&gt;&lt;code&gt;wofi&lt;/code&gt;&lt;/a&gt; with a couple of plugins and lots of configuration.&lt;/p&gt;
&lt;h2 id="editors" class="relative group"&gt;Editors &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#editors" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;I spend a lot of time in an editor. As I wrote &lt;a href="https://jnsgr.uk/uses" target="_blank" rel="noreferrer"&gt;last year&lt;/a&gt;, I&amp;rsquo;ve been using &lt;code&gt;neovim&lt;/code&gt; and Visual Studio Code for some years. I never &amp;ldquo;managed&amp;rdquo; Visual Studio Code with NixOS because I always found their settings sync to be quite sufficient.&lt;/p&gt;
&lt;p&gt;My &lt;a href="https://github.com/jnsgruk/nixos-config/blob/aad045010b1ac61d271858dd5f4c2fa8dcb6e5d4/home/common/shell/vim.nix" target="_blank" rel="noreferrer"&gt;&lt;code&gt;nvim&lt;/code&gt; config&lt;/a&gt; wasn&amp;rsquo;t too complicated - though it is made to look simpler because Home Manager abstracts away the details of managing plugins. I hadn&amp;rsquo;t taken the time to set up language server support, code completion or other creature comforts that one might expect from an editor in 2025.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;d dabbled before with &lt;a href="https://helix-editor.com/" target="_blank" rel="noreferrer"&gt;Helix&lt;/a&gt;, a modal command-line editor not dissimilar from &lt;code&gt;vim&lt;/code&gt;. Helix comes with a lot more out of the box: it supports the Language Server Protocol (LSP), has many built in colour schemes, supports fuzzy finding files/buffers, project wide search and more. The keymap took some practice, but my entire configuration amounts to 8 lines including some blank lines and provides many more modern features.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;catppuccin_macchiato&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;cursorline&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;text-width&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;rulers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lsp&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;display-inlay-hints&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;There is a separate file with some LSP configuration, but only a few more lines. Once I got this set up, I spent about 8 weeks using &lt;em&gt;just&lt;/em&gt; Helix to make sure that the keymap and operating model were sufficiently burned in to my mind. I&amp;rsquo;ve been really impressed - Helix is fast, the default features are great and I don&amp;rsquo;t anticipate returning to &lt;code&gt;vim&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On the desktop side, I&amp;rsquo;d was intrigued by &lt;a href="https://zed.dev/" target="_blank" rel="noreferrer"&gt;Zed&lt;/a&gt;. I don&amp;rsquo;t always feel the need for a desktop editor, but there are projects that I prefer working on in a more graphical environment. I last tried Zed about 18 months ago and found it a little too sparse on features, but things have really evolved since then and there is an encouraging rate of change on the project. I&amp;rsquo;ve been using it most days for the last 4-5 months, and while it still lacks some of the polish (and features) of Visual Studio Code, it&amp;rsquo;s significantly lighter on resources, and I&amp;rsquo;m much happier with the defaults (details below)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;ui_font_size&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;buffer_font_size&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;theme&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;mode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;system&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;light&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Catppuccin Latte&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;dark&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Catppuccin Macchiato&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;buffer_font_family&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MesloLGMDZ Nerd Font Mono&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;ui_font_family&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;.SystemUIFont&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;base_keymap&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;SublimeText&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="terminal" class="relative group"&gt;Terminal &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#terminal" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;I switched to &lt;code&gt;zsh&lt;/code&gt; around 2013 and have used it every day since: starting with the infamous &lt;a href="https://ohmyz.sh/" target="_blank" rel="noreferrer"&gt;Oh My Zsh&lt;/a&gt;, &lt;a href="https://github.com/Powerlevel9k/powerlevel9k" target="_blank" rel="noreferrer"&gt;powerlevel9k&lt;/a&gt;, and subsequently &lt;a href="https://github.com/romkatv/powerlevel10k" target="_blank" rel="noreferrer"&gt;powerlevel10k&lt;/a&gt;, and finally settling on &lt;a href="https://starship.rs/" target="_blank" rel="noreferrer"&gt;Starship&lt;/a&gt; with a couple of &lt;code&gt;zsh&lt;/code&gt; plugins such as &lt;a href="https://github.com/zsh-users/zsh-autosuggestions" target="_blank" rel="noreferrer"&gt;&lt;code&gt;zsh-autosuggestions&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://github.com/zsh-users/zsh-syntax-highlighting" target="_blank" rel="noreferrer"&gt;&lt;code&gt;zsh-syntax-highlighting&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My &lt;code&gt;zsh&lt;/code&gt; config had become quite complex - an area in which NixOS/Home Manager really helped by providing (mostly)neat abstractions for plugins and &lt;code&gt;starship&lt;/code&gt; integration, but the equivalent configuration on Ubuntu would have been 100s of lines of &lt;code&gt;zsh&lt;/code&gt;, notwithstanding the need to load plugins in the right order, etc.&lt;/p&gt;
&lt;p&gt;Most of the configuration I was doing with &lt;code&gt;zsh&lt;/code&gt; was to imitate &lt;a href="https://fishshell.com/" target="_blank" rel="noreferrer"&gt;&lt;code&gt;fish&lt;/code&gt;&lt;/a&gt;. I&amp;rsquo;d tried &lt;code&gt;fish&lt;/code&gt; in the past, but reverted when I couldn&amp;rsquo;t use &lt;code&gt;sudo !!&lt;/code&gt;, or &lt;code&gt;/some/command $!&lt;/code&gt; and other tricks. I&amp;rsquo;d been following &lt;code&gt;fish&lt;/code&gt;&amp;rsquo;s rewrite and decided to give it another go, and have stuck with it since. It fits my JFUI mantra perfectly, leaving me with just a few lines of config for essentially identical functionality:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; fish_greeting &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;fish_add_path ~/.nix-profile/bin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;fish_add_path ~/.local/bin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;fish_add_path ~/.cargo/bin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;fish_add_path ~/go/bin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;fish_add_path ~/scripts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; status is-interactive
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; starship init fish &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;source&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; fzf --fish &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;source&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; atuin init fish --disable-up-arrow &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;source&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;end
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; -gx EDITOR hx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; -gx SUDO_EDITOR hx
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;I still occasionally fall foul of typing &lt;code&gt;sudo !!&lt;/code&gt;, but overall I&amp;rsquo;ve found &lt;code&gt;fish&lt;/code&gt; to be an excellent interactive shell replacement. In particular, the native tab completion support is leagues ahead of anything I ever managed to configure with &lt;code&gt;zsh&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I moved from Alacritty to &lt;a href="https://ghostty.org/" target="_blank" rel="noreferrer"&gt;Ghostty&lt;/a&gt;, which has been absolutely excellent. It&amp;rsquo;s wicked fast, it has my favourite colour scheme built in, and I just love the way &lt;a href="https://github.com/mitchellh" target="_blank" rel="noreferrer"&gt;@mitchellh&lt;/a&gt; has set the project up for success in the long term. It also fits in nicely with my minimally configured applications, with excellent defaults out of the box.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;catppuccin-macchiato&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;font-family&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;MesloLGMDZ Nerd Font Mono&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;font-size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;14&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;window-padding-x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;window-padding-y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;window-decoration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Finally: &lt;a href="https://github.com/tmux/tmux" target="_blank" rel="noreferrer"&gt;tmux&lt;/a&gt;, which I had been happily using for many years, but slowly collecting configuration for. I decided to give &lt;a href="https://zellij.dev/" target="_blank" rel="noreferrer"&gt;Zellij&lt;/a&gt; a try, and haven&amp;rsquo;t looked back. It also has a hellishly complicated configuration in my case 😉:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-kdl" data-lang="kdl"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nl"&gt;theme&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;catppuccin-macchiato&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nl"&gt;default_layout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;compact&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nl"&gt;show_startup_tips&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="software-availability" class="relative group"&gt;Software Availability &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#software-availability" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;I always felt incredibly spoiled by the vast availability of software for NixOS, and even more so that the contribution model was so simple that I was able to augment to collection myself.&lt;/p&gt;
&lt;p&gt;On Ubuntu, I use Snaps wherever possible and fall back to archive and installing software with &lt;code&gt;apt&lt;/code&gt; where it makes sense. If neither of those have what I need, I use the Nix package manager, which works well on Ubuntu. While some of the &amp;ldquo;additional&amp;rdquo; software might be installable using &lt;code&gt;go install&lt;/code&gt;, or &lt;code&gt;cargo install&lt;/code&gt;, or other package managers like &lt;code&gt;brew&lt;/code&gt;, &lt;code&gt;flakpak&lt;/code&gt;, &lt;code&gt;npm&lt;/code&gt;, etc., I wanted to keep things as simple as possible, so if it&amp;rsquo;s not available from Ubuntu-native sources I get it from &lt;code&gt;nixpkgs&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve included what I&amp;rsquo;m actually getting from the Snap store (63 snaps), and from &lt;code&gt;nixpkgs&lt;/code&gt; (21 packages) below.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Installed snaps&lt;/summary&gt;
&lt;pre&gt;
❯ snap list | tail -n+2
agendrr 0.1.1 3 latest/stable jnsgruk* -
astral-uv 0.7.13 627 latest/stable lengau classic
audacity 3.7.1 1208 latest/candidate snapcrafters* -
bare 1.0 5 latest/stable canonical** base
bitwarden 2025.5.1 140 latest/stable bitwarden** -
charmcraft 3.4.6 6672 latest/stable canonical** classic
code 18e3a1ec 197 latest/stable vscode** classic
core 16-2.61.4-20250508 17212 latest/stable canonical** core
core18 20250523 2887 latest/stable canonical** base
core20 20250526 2599 latest/stable canonical** base
core22 20250528 2010 latest/stable canonical** base
core24 20250526 1006 latest/stable canonical** base
desktop-security-center 0+git.f7ad73a 59 1/stable/… canonical** -
discord 0.0.98 243 latest/candidate snapcrafters* -
docker 28.1.1+1 3265 latest/stable canonical** -
dotrun 1.4.8 85 latest/stable canonicalwebteam -
ffmpeg-2404 7.1.1 75 latest/stable snapcrafters* -
firefox 139.0.4-1 6316 latest/stable/… mozilla** -
firmware-updater 0+git.22198be 167 1/stable/… canonical** -
ghstat 0.4.1 91 latest/stable jnsgruk* -
ght 1.11.7 110 latest/edge tbmb -
gimp 3.0.4 525 latest/stable snapcrafters* -
gnome-3-28-1804 3.28.0-19-g98f9e67.98f9e67 198 latest/stable canonical** -
gnome-3-34-1804 0+git.3556cb3 93 latest/stable canonical** -
gnome-42-2204 0+git.38ea591 202 latest/stable/… canonical** -
gnome-46-2404 0+git.d9f8bf6-sdk0+git.c8a281c 90 latest/stable canonical** -
go 1.24.4 10907 latest/stable canonical** classic
gopls 0.19.0 1089 latest/stable alexmurray* classic
goreleaser 2.10.2 1060 latest/stable caarlos0 classic
gtk-common-themes 0.1-81-g442e511 1535 latest/stable/… canonical** -
helix 25.01.1 91 latest/stable lauren-brock classic
icloudpd 1.28.1 12 latest/stable jnsgruk* -
jhack 0.4.4.0.13 461 latest/stable ppasotti -
jq 1.5+dfsg-1 6 latest/stable mvo* -
juju 3.6.7 31266 3/stable canonical** -
kubectl 1.33.2 3609 latest/stable canonical** classic
lxd 5.21.3-c5ae129 33110 5.21/stable canonical** -
mattermost-desktop 5.12.1 789 latest/stable snapcrafters* -
mesa-2404 24.2.8-snap183 887 latest/stable canonical** -
multipass 1.15.1 14535 latest/stable canonical** -
node 22.16.0 10226 22/stable iojs** classic
obsidian 1.8.10 47 latest/stable obsidianmd classic
pinta 3.0.1 56 latest/stable james-carroll* -
prompting-client 0+git.d542a5d 104 1/stable/… canonical** -
rambox 2.4.1 44 latest/stable ramboxapp** -
rockcraft 1.12.0 3367 latest/stable canonical** classic
ruff 0.11.13 1377 latest/stable lengau -
rustup 1.27.1 1471 latest/stable canonical** classic
shellcheck v0.10.0 1725 latest/stable koalaman -
shfmt 3.5.1 33 latest/stable ankushpathak -
signal-desktop 7.58.0 799 latest/candidate snapcrafters* -
snap-store 0+git.90575829 1270 2/stable/… canonical** -
snapcraft 8.9.4 15082 latest/stable canonical** classic
snapd 2.68.5 24718 latest/stable canonical** snapd
snapd-desktop-integration 0.9 253 latest/stable/… canonical** -
sublime-merge 2102 95 latest/stable snapcrafters* classic
thonny 4.1.7 239 latest/stable sameersharma2006 -
thunderbird 128.11.1esr-1 737 latest/stable canonical** -
todoist 9.17.0 1340 latest/stable doist** -
typescript-language-server 4.3.4 211 latest/stable alexmurray* -
yazi shipped 293 latest/stable sxyazi classic
yq v4.44.5 2634 latest/stable mikefarah -
zellij 0.42.2 41 latest/stable dominz88 classic
&lt;/pre&gt;
&lt;/details&gt;
&lt;details&gt;
&lt;summary&gt;Installed Nix packages&lt;/summary&gt;
&lt;pre&gt;
❯ nix profile list | grep -Po "Name:[ ]*\K.+\$"
atuin
bash-language-server
cargo-udeps
deadnix
fzf
gh
gofumpt
nil
nixd
nixfmt-rfc-style
prettier
pyright
python-lsp-server
spread
starship
statix
taplo
terraform-ls
typos-lsp
vscode-langservers-extracted
yaml-language-server
&lt;/pre&gt;
&lt;/details&gt;
&lt;p&gt;I continue to find Nix development shells useful, and even &lt;a href="https://github.com/jnsgruk/jnsgr.uk/blob/5f9f2fe2ced2416e8a1fb3116d88d1b51c9fdbc7/flake.nix#L99-L122" target="_blank" rel="noreferrer"&gt;use one&lt;/a&gt; to develop this site.&lt;/p&gt;
&lt;h2 id="configuration-management" class="relative group"&gt;Configuration Management &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#configuration-management" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;In the past I&amp;rsquo;ve used all kinds of scripts, Ansible playbooks and dotfile managers to solve this problem, and its a problem that was solved very elegantly by NixOS/Home Manager. I experimented with Home Manager on Ubuntu to manage dotfiles and configuration, but found the experience had more rough edges than I would like, and didn&amp;rsquo;t really adhere to my JFUI principles.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve settled on a directory full of idempotent, single-purpose scripts which get executed by a wrapper named &lt;code&gt;provision&lt;/code&gt;. This is somewhat inspired by &lt;a href="https://omakub.org/" target="_blank" rel="noreferrer"&gt;Omakub&lt;/a&gt;, but without the menus and configuration they supply to allow their users some customisation. The scripts install packages, write configuration with tools like &lt;code&gt;gsettings&lt;/code&gt; and symlink configuration into place where needed:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;❯ ls
app-1password dev-python tool-agendrr
app-chrome dev-rust tool-atuin
app-flameshot font-meslo tool-gearlever
app-ghostty hw-yubikey tool-gh
app-obsidian kara-audioengine tool-git
app-pinta kara-backup tool-helix
app-rambox kara-data-disk tool-junction
app-signal kara-hiring-automation tool-lxd
app-sublime-merge kara-hiring-reports tool-multipass
app-thunderbird provision tool-podman
app-todoist system-flatpak tool-spread
configs system-fs tool-starship
dev-charms system-gnome tool-syncthing
dev-containers system-gnome-extensions tool-tailscale
dev-go system-nix tool-zed
dev-node system-shell tool-zellij
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;An example of a specific script, such as &lt;code&gt;tool-zellij&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; -e
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt; dirname &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BASH_SOURCE&lt;/span&gt;&lt;span class="p"&gt;[0]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;pwd&lt;/span&gt; &lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo snap install --classic zellij
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;mkdir -p &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.config/zellij&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ln -sf &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/configs/zellij/config.kdl&amp;#34;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.config/zellij/config.kdl&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The &lt;code&gt;provision&lt;/code&gt; script is similarly simple (and naive):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; -ex
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt; dirname &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BASH_SOURCE&lt;/span&gt;&lt;span class="p"&gt;[0]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;pwd&lt;/span&gt; &lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get upgrade -y
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;categories&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;system hw dev tool app font &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;hostname&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; c in &lt;span class="nv"&gt;$categories&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; x in &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;c&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;-*&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;source&lt;/span&gt; &lt;span class="nv"&gt;$x&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This is &lt;em&gt;just about&lt;/em&gt; satisfactory. I&amp;rsquo;ve got into the habit of only ever installing software by creating the relevant script and configuration. If I don&amp;rsquo;t need it to persist, the work gets done in an ephemeral LXD container/VM then thrown away.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m working on a better solution for this named &lt;code&gt;miso&lt;/code&gt;, short for &amp;ldquo;Make It So&amp;rdquo;. This a homegrown, multi-host configuration management tool for my machines that draws inspiration from &lt;code&gt;cloud-init&lt;/code&gt;, &lt;code&gt;home-manager&lt;/code&gt;, &lt;code&gt;terraform&lt;/code&gt; and a few others. I&amp;rsquo;ll write about that in a future post when the code is a little more complete, but there is an example of an early configuration format I&amp;rsquo;m targeting available as a &lt;a href="https://gist.github.com/jnsgruk/64b7418183bd3abfbe68e878907608e3" target="_blank" rel="noreferrer"&gt;gist&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Everything in the linked config file is currently implemented and working with a decent suite of integration tests - but I&amp;rsquo;ve got a lot of tidying to do with error handling and such before I release it.&lt;/p&gt;
&lt;h2 id="so-what-about-nix" class="relative group"&gt;So What About Nix? &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#so-what-about-nix" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;I thoroughly enjoyed my adventures with Nix, and I consider having learned how to package software with Nix and use the available tooling to manage servers, desktops and development shells to have been incredibly worthwhile.&lt;/p&gt;
&lt;p&gt;Even &lt;em&gt;if&lt;/em&gt; I were to never touch Nix again, the general packaging and distribution engineering skills I learned have been invaluable, and I&amp;rsquo;m grateful to everyone who helped me on that journey through Matrix chats, Pull Requests and Mastodon interactions.&lt;/p&gt;
&lt;p&gt;I remain active on the ~35 packages in &lt;a href="https://github.com/NixOS/nixpkgs" target="_blank" rel="noreferrer"&gt;&lt;code&gt;nixpkgs&lt;/code&gt;&lt;/a&gt; for which I&amp;rsquo;m the maintainer. I continue to use Nix for development shells, CI and for certain packages on my Ubuntu machines. I have archived my &lt;a href="https://github.com/jnsgruk/nixos-config" target="_blank" rel="noreferrer"&gt;flake&lt;/a&gt; for now because it&amp;rsquo;s not being maintained, but I&amp;rsquo;ve left it there in case there are any patterns that might be useful for others.&lt;/p&gt;
&lt;h2 id="summary" class="relative group"&gt;Summary &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#summary" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Ubuntu has been very stable on my desktop, server and both of my laptops. I&amp;rsquo;ve enjoyed the level of integration and polish that comes with no effort in the desktop environment, and managing less configuration has been a freeing experience - even if some of my apps no longer have matching themes 😱.&lt;/p&gt;
&lt;p&gt;Provisioning and configuration management are less structured and more cumbersome in Ubuntu, but that has driven me to build my own tool which was good fun, and gave me a nice challenge to solve through my journey learning Rust! I hope to learn from the project in a way that helps inform the development of Ubuntu itself in future releases.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re into numbers, here are the stats for my renewed &amp;ldquo;config&amp;rdquo; directory, which contains all of the text-based configuration &amp;amp; scripts for my machines:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;----------------------------------------------------------
Language files blank comment code
----------------------------------------------------------
Bourne Again Shell 47 154 81 413
TOML 3 13 1 53
Fish Shell 1 13 3 38
JSON 1 0 0 35
----------------------------------------------------------
SUM: 52 180 85 539
----------------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;From 3982 lines, to 539 lines, and much of that could be reduced if it wasn&amp;rsquo;t for the slightly repetitive nature of maintaining separate, idempotent scripts. Not bad.&lt;/p&gt;
&lt;p&gt;As much as I feared the transition, my journey back to Ubuntu has been very enjoyable. I&amp;rsquo;m not &amp;ldquo;quitting Nix&amp;rdquo; or &amp;ldquo;over it&amp;rdquo;, but at least for now I&amp;rsquo;m enjoying a less complex existence with my personal computers.&lt;/p&gt;
&lt;p&gt;Thanks for reading!&lt;/p&gt;</description></item></channel></rss>