<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Homebrew on Carlos Vaz</title>
    <link>https://carlosvaz.com/tags/homebrew/</link>
    <description>Recent content in Homebrew on Carlos Vaz</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-US</language>
    <managingEditor>carlos@carjorvaz.com (Carlos Vaz)</managingEditor>
    <webMaster>carlos@carjorvaz.com (Carlos Vaz)</webMaster>
    <lastBuildDate>Sun, 05 May 2024 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://carlosvaz.com/tags/homebrew/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Declarative macOS management with nix-darwin and home-manager</title>
      <link>https://carlosvaz.com/posts/declarative-macos-management-with-nix-darwin-and-home-manager/</link>
      <pubDate>Sun, 05 May 2024 00:00:00 +0000</pubDate><author>carlos@carjorvaz.com (Carlos Vaz)</author>
      <guid>https://carlosvaz.com/posts/declarative-macos-management-with-nix-darwin-and-home-manager/</guid>
      <description>&lt;p&gt;For the past year, I&amp;rsquo;ve been daily driving the M1 Macbook Air with 8GB of RAM and 240GB of storage.&#xA;Most of my life I&amp;rsquo;ve mostly been an Apple skeptic but this laptop changed my views in some aspects.&lt;/p&gt;&#xA;&lt;p&gt;But having just come from NixOS, I was missing that declarative mindset in being able to manage my system from a single file.&#xA;Luckily, with nix-darwin and home-manager I was able to get my system mostly declarative, at least declarative enough for my needs.&#xA;This also allowed to manage the Mac with my existing NixOS flake, so I could reuse existing configurations, like my zsh home-manager configuration.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>For the past year, I&rsquo;ve been daily driving the M1 Macbook Air with 8GB of RAM and 240GB of storage.
Most of my life I&rsquo;ve mostly been an Apple skeptic but this laptop changed my views in some aspects.</p>
<p>But having just come from NixOS, I was missing that declarative mindset in being able to manage my system from a single file.
Luckily, with nix-darwin and home-manager I was able to get my system mostly declarative, at least declarative enough for my needs.
This also allowed to manage the Mac with my existing NixOS flake, so I could reuse existing configurations, like my zsh home-manager configuration.</p>
<h2 id="installation">Installation</h2>
<p>Starting from a fresh macOS installation, this is how I bootstrapped my nix-darwin configuration:</p>
<ol>
<li>
<p>Install Nix:</p>





<pre tabindex="0"><code class="language-nil" data-lang="nil">curl -L https://nixos.org/nix/install | sh</code></pre><p>For this step, you could also try to use the <a href="https://github.com/DeterminateSystems/nix-installer">Determinate Systems nix-installer</a>, which I&rsquo;ve read good things about, although the official installer also worked just fine.</p>
</li>
<li>
<p>Enable flakes:</p>





<pre tabindex="0"><code class="language-nil" data-lang="nil">mkdir -p ~/.config/nix
cat &lt;&lt;EOF &gt; ~/.config/nix/nix.conf
experimental-features = nix-command flakes
EOF</code></pre></li>
<li>
<p>Use nix run to run the first rebuild:</p>





<pre tabindex="0"><code class="language-nil" data-lang="nil">nix run nix-darwin -- switch --flake &lt;path_to_nix_darwin_configuration&gt;</code></pre></li>
<li>
<p>Use darwin-rebuild normally:</p>





<pre tabindex="0"><code class="language-nil" data-lang="nil">darwin-rebuild switch --flake &lt;path_to_nix_darwin_configuration&gt;</code></pre></li>
</ol>
<h2 id="declarative-homebrew-package-management">Declarative Homebrew package management</h2>
<p>One of the key reasons for using nix-darwin is not only access to the nix package manager, but being able to use Homebrew declaratively.</p>
<p>Homebrew is the de facto package manager for macOS.
Most programs you can think are available over there, especially CLI tools but also GUI apps in the form of casks.</p>
<p>So we would very much like to keep access to those apps, only adding declarativeness to the workflow.</p>
<p>Another reason for using Homebrew is simply because nixpkgs cannot yet replace it, especially when it comes to GUI apps.
Some could say that this will never happen because it&rsquo;s out of scope of the nixpkgs project, which I guess is reasonable.</p>
<p>To use Homebrew, we first have to <a href="https://brew.sh/">install it manually</a>:</p>





<pre tabindex="0"><code class="language-nil" data-lang="nil">$ /bin/bash -c &#34;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&#34;</code></pre><p>After that, we can use the <code>homebrew</code> module from nix-darwin, like the following example:</p>





<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nix" data-lang="nix"><span style="display:flex;"><span><span style="color:#75715e"># I&#39;d rather not have telemetry on my package manager.</span>
</span></span><span style="display:flex;"><span>environment<span style="color:#f92672">.</span>variables<span style="color:#f92672">.</span>HOMEBREW_NO_ANALYTICS <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;1&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>homebrew <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>  enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  onActivation <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    autoUpdate <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>    cleanup <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;zap&#34;</span>;
</span></span><span style="display:flex;"><span>    upgrade <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>  };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  brews <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;coreutils&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;direnv&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;fd&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;gcc&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;git&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;grep&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;ripgrep&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;trash&#34;</span>
</span></span><span style="display:flex;"><span>  ];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># Update these applicatons manually.</span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># As brew would update them by unninstalling and installing the newest</span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># version, it could lead to data loss.</span>
</span></span><span style="display:flex;"><span>  casks <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;docker&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;emacs-mac&#34;</span> <span style="color:#75715e"># Emacs fork with better macOS support</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;firefox&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;iterm2&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;monitorcontrol&#34;</span> <span style="color:#75715e"># Brightness and volume controls for external monitors.</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;ukelele&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;unnaturalscrollwheels&#34;</span> <span style="color:#75715e"># Enable natural scrolling in the trackpad but regular scroll on an external mouse</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;utm&#34;</span> <span style="color:#75715e"># Virtual Machine Manager</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;visual-studio-code&#34;</span>
</span></span><span style="display:flex;"><span>  ];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  taps <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;railwaycat/emacsmacport&#34;</span> <span style="color:#75715e"># emacs-mac</span>
</span></span><span style="display:flex;"><span>  ];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  masApps <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    Tailscale <span style="color:#f92672">=</span> <span style="color:#ae81ff">1475387142</span>; <span style="color:#75715e"># App Store URL id</span>
</span></span><span style="display:flex;"><span>  };
</span></span><span style="display:flex;"><span>};</span></span></code></pre></div><p>One of the most important features in managing packages this way is that <em>removing</em> packages from the configuration above also uninstalls them, which is one of the big features I was missing from NixOS.
This avoids the traditional buildup of unused and forgotten packages in the system.</p>
<p>You supposedly can also use this to manage App Store apps but I found that I always needed to manually install them first (so they could be registered to my account?), so it wasn&rsquo;t as useful.</p>
<h2 id="other-noteworthy-options">Other noteworthy options</h2>
<p>The <a href="https://daiderd.com/nix-darwin/manual/index.html">list of options is quite extensive</a>, here are some that I found useful:</p>
<h3 id="nix-management">Nix management</h3>





<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nix" data-lang="nix"><span style="display:flex;"><span><span style="color:#75715e"># Auto upgrade nix package and the daemon service.</span>
</span></span><span style="display:flex;"><span>services<span style="color:#f92672">.</span>nix-daemon<span style="color:#f92672">.</span>enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>nix <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>  package <span style="color:#f92672">=</span> pkgs<span style="color:#f92672">.</span>nix;
</span></span><span style="display:flex;"><span>  gc<span style="color:#f92672">.</span>automatic <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>  optimise<span style="color:#f92672">.</span>automatic <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>  settings <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    auto-optimise-store <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>    experimental-features <span style="color:#f92672">=</span> [ <span style="color:#e6db74">&#34;nix-command&#34;</span> <span style="color:#e6db74">&#34;flakes&#34;</span> ];
</span></span><span style="display:flex;"><span>  };
</span></span><span style="display:flex;"><span>};</span></span></code></pre></div><h3 id="sudo-with-touch-id"><code>sudo</code> with Touch ID</h3>
<p>Just like when macOS asks for elevated privileges, this makes <code>sudo</code> also work with Touch ID, which I find quite ergonomic:</p>





<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nix" data-lang="nix"><span style="display:flex;"><span>security<span style="color:#f92672">.</span>pam<span style="color:#f92672">.</span>enableSudoTouchIdAuth <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;</span></span></code></pre></div><h3 id="keyboard-tweaks">Keyboard tweaks</h3>
<p>These are some keyboard tweaks like turning caps lock into ctrl and disabling press and hold for diacritics:</p>





<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nix" data-lang="nix"><span style="display:flex;"><span>system<span style="color:#f92672">.</span>keyboard<span style="color:#f92672">.</span>enableKeyMapping <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>system<span style="color:#f92672">.</span>keyboard<span style="color:#f92672">.</span>remapCapsLockToControl <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Disable press and hold for diacritics.</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># I want to be able to press and hold j and k</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># in VSCode with vim keys to move around.</span>
</span></span><span style="display:flex;"><span>system<span style="color:#f92672">.</span>defaults<span style="color:#f92672">.</span>NSGlobalDomain<span style="color:#f92672">.</span>ApplePressAndHoldEnabled <span style="color:#f92672">=</span> <span style="color:#66d9ef">false</span>;</span></span></code></pre></div><h2 id="simple-nix-darwin-flake">Simple nix-darwin flake</h2>
<p>Flakes are all the rage right now but they can be daunting to new users.</p>
<p>Here&rsquo;s a simple nix-darwin flake to get you started, which also makes it easy to use home-manager:</p>
<p><code>flake.nix</code>:</p>





<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nix" data-lang="nix"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  inputs <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    nixpkgs<span style="color:#f92672">.</span>url <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;github:nixos/nixpkgs/nixos-23.11&#34;</span>;
</span></span><span style="display:flex;"><span>    nixpkgs-darwin<span style="color:#f92672">.</span>url <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;github:NixOS/nixpkgs/nixpkgs-23.11-darwin&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    nix-darwin<span style="color:#f92672">.</span>url <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;github:LnL7/nix-darwin/master&#34;</span>;
</span></span><span style="display:flex;"><span>    nix-darwin<span style="color:#f92672">.</span>inputs<span style="color:#f92672">.</span>nixpkgs<span style="color:#f92672">.</span>follows <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;nixpkgs-darwin&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    home-manager<span style="color:#f92672">.</span>url <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;github:nix-community/home-manager/release-23.11&#34;</span>;
</span></span><span style="display:flex;"><span>    home-manager<span style="color:#f92672">.</span>inputs<span style="color:#f92672">.</span>nixpkgs<span style="color:#f92672">.</span>follows <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;nixpkgs&#34;</span>;
</span></span><span style="display:flex;"><span>  };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  outputs <span style="color:#f92672">=</span> { self<span style="color:#f92672">,</span> <span style="color:#f92672">...</span> }<span style="color:#f92672">@</span>inputs:
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      darwinConfigurations<span style="color:#f92672">.</span><span style="color:#e6db74">&#34;&lt;hostname&gt;&#34;</span> <span style="color:#f92672">=</span> inputs<span style="color:#f92672">.</span>nix-darwin<span style="color:#f92672">.</span>lib<span style="color:#f92672">.</span>darwinSystem {
</span></span><span style="display:flex;"><span>        system <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;aarch64-darwin&#34;</span>;
</span></span><span style="display:flex;"><span>        specialArgs <span style="color:#f92672">=</span> { <span style="color:#66d9ef">inherit</span> inputs self; };
</span></span><span style="display:flex;"><span>        modules <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">./hosts/mac.nix</span>
</span></span><span style="display:flex;"><span>          inputs<span style="color:#f92672">.</span>home-manager<span style="color:#f92672">.</span>darwinModules<span style="color:#f92672">.</span>home-manager
</span></span><span style="display:flex;"><span>          {
</span></span><span style="display:flex;"><span>            home-manager<span style="color:#f92672">.</span>useGlobalPkgs <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>            home-manager<span style="color:#f92672">.</span>useUserPackages <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>          }
</span></span><span style="display:flex;"><span>        ];
</span></span><span style="display:flex;"><span>      };
</span></span><span style="display:flex;"><span>    };
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><p>Where <code>./hosts/mac.nix</code> would be your nix-darwin configuration file, with the previous snippets.</p>
<h3 id="home-manager">home-manager</h3>
<p>Now, we can use home-manager in our configuration.</p>
<p>Here are some examples:</p>





<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nix" data-lang="nix"><span style="display:flex;"><span><span style="color:#75715e"># Import existing home-manager configuration</span>
</span></span><span style="display:flex;"><span>imports <span style="color:#f92672">=</span> [ <span style="color:#e6db74">&#34;</span><span style="color:#e6db74">${</span>self<span style="color:#e6db74">}</span><span style="color:#e6db74">/profiles/home/zsh.nix&#34;</span> ];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Required by home-manager.</span>
</span></span><span style="display:flex;"><span>users<span style="color:#f92672">.</span>users<span style="color:#f92672">.</span>john<span style="color:#f92672">.</span>home <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;/Users/john&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>home-manager<span style="color:#f92672">.</span>users<span style="color:#f92672">.</span>john <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    programs <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>      zsh <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>        enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>        autocd <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>        defaultKeymap <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;emacs&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        enableCompletion <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>        enableVteIntegration <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>        enableAutosuggestions <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>        syntaxHighlighting<span style="color:#f92672">.</span>enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        history <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>          expireDuplicatesFirst <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>          extended <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>          ignoreDups <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>        };
</span></span><span style="display:flex;"><span>      };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      direnv <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>        enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>        nix-direnv<span style="color:#f92672">.</span>enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>      };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      dircolors<span style="color:#f92672">.</span>enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>      fzf<span style="color:#f92672">.</span>enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>      starship<span style="color:#f92672">.</span>enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>      zoxide<span style="color:#f92672">.</span>enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      initExtra <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;&#39;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        # Enable iTerm2 shell integration.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        test -e &#34;~/.iterm2_shell_integration.zsh&#34; &amp;&amp; source &#34;~/.iterm2_shell_integration.zsh&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">      &#39;&#39;</span>;
</span></span><span style="display:flex;"><span>    };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  home<span style="color:#f92672">.</span>stateVersion <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;23.11&#34;</span>;
</span></span><span style="display:flex;"><span>};</span></span></code></pre></div><p>This allows you to consolidate your dispersed dotfiles into a single source of truth, the nix-darwin config file.
To find options for other programs home-manager supports, I found the (unofficial?) <a href="https://home-manager-options.extranix.com/">home manager options search</a> quite useful.</p>
<p>I believe you can also use the <code>home.file</code> options to write to arbitrary files in your home directory.</p>
<h2 id="closing-remarks">Closing remarks</h2>
<p>This experience turned the macOS experience much more tolerable.</p>
<p>And it really is true: Apple Silicon is game-changing.
Compared to the ThinkPads I was used to, the MacBook had a great screen (brightness, color and HiDPI, although I would skip the glossy finish), great speakers, was way faster, and didn&rsquo;t heat up even though it&rsquo;s passively cooled, which also means that there&rsquo;s no fan noise.</p>
<p>I managed to buy this one used for 550€, which is probably the best deal for a laptop in mid-2024 for most people.
But despite all of that, there&rsquo;s a dealbreaker: the keyboard was starting to give me symptoms of RSI, just like <a href="https://fortintam.com/blog/apple-aluminium-keyboard-and-repetitive-strain-injury-rsi/">this anecdote</a>.
My experience was pretty much the same and now that I&rsquo;ve stopped using it, my hands feel much better.
I really can&rsquo;t justify using the laptop if that has implications on my physical health.</p>
<p>Also, even though I really tried, I didn&rsquo;t find macOS window management very ergonomic.
Full-screen apps being workspaces, the workspaces shuffling around chaotically (most recently used? but only if you click the app from the dock?), having to swipe around looking for what I wanted or always having to go to Mission Control.
I found it really confusing, perhaps because I&rsquo;m not the kind of user to always be using a single window at once.</p>
<p>I&rsquo;m aware that there are tiling window managers for macOS, some that even work without disable System Integrity Protection, but by that point: why even use macOS if you&rsquo;re not using like it was designed?</p>
<p>But if you dislike macOS but tolerate the keyboard, then an Apple Silicon Macbook is probably one of the greatest Linux laptops I&rsquo;ve ever used, but I&rsquo;ll leave that to a future blog post.</p>
<p>Finally, Apple has some questionable practices, although they&rsquo;re mostly hardware-related instead of software-related, which I do prefer, if I had to pick my poison from the selection of behaviours of big tech companies.
What I mean by this is that, until now, Apple&rsquo;s software although proprietary, (seems to) respect user privacy, doesn&rsquo;t fill available screen space with ads and doesn&rsquo;t force updates on its users while they&rsquo;re working.</p>
<p>The reason for this seems to be that Apple&rsquo;s business model is selling expensive hardware, so they don&rsquo;t need to monetize their software as much as other companies.
This also means that, if you&rsquo;re buying new, you&rsquo;ll have to pay 200€ for 8GB RAM upgrade increments and 200€ for a 240GB SSD storage increment, because they&rsquo;re both soldered in.
You can avoid falling into the scam by only buying the base models, which will make the most out of your money, or by buying used.
The problem is: I also found 8GB way too restricting, I&rsquo;d really recommend going for 16GB minimum.
I managed to make the experience a bit better by using <a href="https://github.com/rNeomy/auto-tab-discard">Auto Tab Discard</a> in Firefox but I still seemed to be under intense memory pressure all the time.</p>
<p>Besides that, I felt no need to buy anything more recent than the M1 MacBook Air.
Not only that, it seems that the M1 MacBook Air is better than the M2 MacBook Air in some aspects, like having greater memory bandwidth and faster storage, because it has 2 NAND chips instead of just 1.</p>
<p>Bottom line is that despite Apple arguably running a hardware upgrade pricing scam, trying to lock you in to the walled garden/ecosystem and muffling down right to repair (while making their hardware harder to repair, especially by soldering in SSDs that do have a very finite lifespan), I find their laptops are really good, if you can tolerate the keyboards.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://gist.github.com/jmatsushita/5c50ef14b4b96cb24ae5268dab613050">https://gist.github.com/jmatsushita/5c50ef14b4b96cb24ae5268dab613050</a></li>
<li><a href="https://github.com/LnL7/nix-darwin">https://github.com/LnL7/nix-darwin</a></li>
<li><a href="https://daiderd.com/nix-darwin/manual/index.html#sec-options">https://daiderd.com/nix-darwin/manual/index.html#sec-options</a></li>
</ul>
]]></content:encoded>
    </item>
  </channel>
</rss>
