macOS に Nix をインストールする

## 概要

macOS に Nix、 nix-darwin、Home Manager をインストールして使えるようにするための手順を説明します。

それぞれの役割はざっくり以下です。

- [Nix](https://nix.dev/manual/nix/2.24/introduction): パッケージマネージャ
    - Profiles 機能によるパッケージのインストール（Brew や apt のような立ち位置）
    - nix-shell によるパッケージのお試し
    - 他の人が、または自分で作ったソフトウェアのビルド・分配
- [nix-darwin](https://github.com/nix-darwin/nix-darwin): macOS の設定管理
    - Nix 言語によるシステムの設定
- [Home Manager](https://github.com/nix-community/home-manager): ユーザごとの環境設定
    - ユーザ環境へのパッケージのインストールおよび設定（例: Zsh を入れて Oh-My-Zsh のテーマを適用する）

それぞれの簡単な使い方は、インストール手順の合間で少しずつ説明していきます。  
また、別ページで NixOS や Nix Flakes および周辺概念について説明したことがあるので、よろしければそちらもご参照ください。

https://qiita.com/kino-ma/items/85277c6ca6e3fd19c322

https://zenn.dev/kino_ma/articles/f2a4df384b91a4

そして、 Nix の力をを最大限引き出せる NixOS という Linux ディストリビューションがあります。  
その設定方法・使い方については asahi さんによる以下の記事が詳しいです。  
当記事では macOS における設定手順を説明しますが、 Nix エコシステムに興味を持ってくださった方は普段使い OS として NixOS を設定してみるのはいかがでしょうか。

https://zenn.dev/asa1984/articles/nixos-is-the-best


## 環境

- macOS Sequoia
- Nix 2.27.1 （執筆時点の最新版）
- nix-darwin 24.11
- Home Manager 24.11


## なぜ Mac で Nix を使うのか？

（長いので読み飛ばしていただいて構いません。ひとことで言うなら、 Nix があれば大体全てが解決するという雑な主張をしています。）

本記事では、先述した通り **Nix パッケージマネージャ**、 **nix-darwin**、 **Home Manager** という三つのシステムをインストールします。

これらはいずれも **Nix 言語** という設定用言語を使用します。  
設定用言語としてみると、 Nix 言語はたとえば JSON や YAML/TOML、 HCL などと同じ働きをすることになります。  
それらの言語と異なるのは、関数や変数の機能を持っており柔軟・動的な記述が可能という点でしょうか。  

しかし上述のシステムを使うだけなら、その差を意識する必要はあまりありません。  
JSON や YAML を書いているのと同じ気持ちでいれば問題ありません。

さて、これら Nix 言語とその周辺システムは、まとめて **Nix エコシステム** と呼ぶことがあります [^ecosystem]。  
Nix エコシステムに共通する特徴として、 **再現性** があります。

[^ecosystem]: 少なくともこの記事ではそう呼ぶことにします。

ここで言う再現性とは、 **ビルドの再現性** を意味します。

Docker を使ったことのある方なら、「一度コンテナを作ればどこでも同じ環境を再現できる」と説明を聞いた、あるいはそう感じたことがあるのではないでしょうか？  
使ったことのない方向けに説明すると、たとえば手元の PC で「Docker コンテナ」と呼ばれる箱庭環境を作成したら、同じ箱庭をクラウド上やデータセンターのサーバ機器上で即座に再現できるのです。  
開発したサービスのプログラムや依存ライブラリをその箱庭にインストールしておけば、サーバ側での環境作成をすっ飛ばしてすぐにサービスを動かし始めることができるというわけです。

そのように、「**一度作成した環境を即座に・確実に再現できる**」のが Nix エコシステムの特長です。

本記事でインストールするシステム群により再現可能になる点は、例えば以下を含みます。

- インストールしたソフトウェア
    - Git、ターミナル、 VSCode、 Discord、 Python、 Docker、などなど
- ソフトウェア環境の隔離
    - 複数バージョンの同じソフトウェアを同居させられる（例：Python 3.10 と 3.11）
- ソフトウェアに対するカスタム設定
    - Git のユーザ名・メールアドレス、シェルや Vim などの細かな設定
- Mac 全体に対する設定
    - フォントの追加、ネットワーク設定、その他「システム環境設定」で変更可能な項目いろいろ

つまり、一度これらの設定を Nix 言語で書き終えたら、その **Nix 言語ファイルを別のパソコンにコピー＋読み込みすれば全く同じ設定が再現できます**。

この利点それぞれを個別に達成するシステムはちらほらあります（各言語の仮想環境管理システム、 Ansible、 Docker、 dotfiles 補助系システムなど）。  
しかし Nix の強みは：

- これら全てを一つのエコシステムでワンストップに達成すること
- 流行が始まっており、一部の有名ソフトウェアが標準で対応していること [^major-software]
- Docker と異なり *仮想化レイヤ* を挟まないので扱いやすく、（特に Mac で）パフォーマンス上の制約もない
- 利用可能なパッケージが非常に多く、 2025年4月時点で **120,000** ものパッケージが利用可能
    - これは apt （たしか数万）や brew （たしか一万未満）よりも圧倒的に多いです

それに個人的には、その出自が学術研究であることも興味深いです [^academia]

[^major-software]: 筆者が使用しているターミナル [WezTerm](https://github.com/wezterm/wezterm)、 次世代の `ls` を謳う [eza](https://github.com/eza-community/eza) など、比較的新しめのソフトウェアが対応しています。といってもソフトウェア側で対応しているのと Nix 側でパッケージングするのに違いは何もありません。

[^academia]: Utrecht 大学で Eelco Dolstra 氏の博士論文として取り組まれました （`Dolstra, Eelco. The purely functional software deployment model. Utrecht University, 2006.`）。また、 USENIX 系の学会である LISA などいくつかの学会にも accept されています （`Dolstra, Eelco, Merijn De Jonge, and Eelco Visser. "Nix: A Safe and Policy-Free System for Software Deployment." LISA. Vol. 4. 2004.`）

また、 Nix は再現性の中でも特に、その **完全性** に注力しています。  
つまり「確実に」再現するための仕組みが充実しているという意味です。

https://nix.dev/manual/nix/2.24/

さて、まとめると Nix はパッケージやシステムの管理において強力な再現性を発揮し、設定を「作る」のも「移植する」のも簡単だということです。  
使いたくなったでしょうか？


## 手順

それでは、 macOS で Nix エコシステムを活用するために大事な三つのソフトウェア **Nix パッケージマネージャ**、 **nix-darwin**、 **Home Manager** の三つをインストールするための手順を説明していきます。


### ① Nix パッケージマネージャ

まずは、 Nix パッケージマネージャをインストールします。

Nix パッケージマネージャの役割は、名前の通り mac 上にパッケージ（ソフトウェア）をインストールしたり管理したりすることです。  
後ほど nix-darwin をインストールするためにも使用します。


#### インストール手順

やることは、公式ページに記載されているコマンドを実行するだけです。

https://nixos.org/download/

```bash
sh <(curl -L https://nixos.org/nix/install)
```

このコマンドを実行すると、ターミナルに以下のような説明が表示されてからインストールスクリプトが起動します。

```
Welcome to the Multi-User Nix Installation

This installation tool will set up your computer with the Nix package
manager. This will happen in a few stages:

1. Make sure your computer doesn't already have Nix. If it does, I
   will show you instructions on how to clean up your old install.

2. Show you what I am going to install and where. Then I will ask
   if you are ready to continue.

3. Create the system users (uids [351..382]) and groups (gid 350)
   that the Nix daemon uses to run builds. To create system users
   in a different range, exit and run this tool again with
   NIX_FIRST_BUILD_UID set.

4. Perform the basic installation of the Nix files daemon.

5. Configure your shell to import special Nix Profile files, so you
   can use Nix.

6. Start the Nix daemon.
```

より詳細を表示させるには、次のプロンプトに `y` と答えます。

```
Would you like to see a more detailed list of what I will do?
[y/n] y


I will:

 - make sure your computer doesn't already have Nix files
   (if it does, I will tell you how to clean them up.)
 - create local users (see the list above for the users I'll make)
 - create a local group (nixbld)
 - install Nix in /nix
 - create a configuration file in /etc/nix
 - set up the "default profile" by creating some Nix-related files in
   /var/root
 - back up /etc/bashrc to /etc/bashrc.backup-before-nix
 - update /etc/bashrc to include some Nix configuration
 - back up /etc/zshrc to /etc/zshrc.backup-before-nix
 - update /etc/zshrc to include some Nix configuration
 - create a Nix volume and a LaunchDaemon to mount it
 - create a LaunchDaemon (at /Library/LaunchDaemons/org.nixos.nix-daemon.plist) for nix-daemon
```

要約すると、ビルド用ユーザや各種ファイルの作成、デーモンの起動など、 Nix を使うためのいろんな作業をするよ！と言っています。

特に問題がなければ、続きの実行を許可して実行を継続します。

```
Ready to continue?
[y/n] y
```

すると、引き続き `sudo` に関する注意事項的なものが表示されます。

Nix インストールスクリプトはシステムに変更を加えるために `sudo` コマンドを多用しますが、その度に確認をとるよ、といった旨の説明がされています。  
許可するために `y` を押して継続させます。

```

---- let's talk about sudo -----------------------------------------------------
This script is going to call sudo a lot. Every time I do, it'll
output exactly what it'll do, and why.

Just like this:

---- sudo execution ------------------------------------------------------------
I am executing:

    $ sudo echo

to demonstrate how our sudo prompts look


This might look scary, but everything can be undone by running just a
few commands. I used to ask you to confirm each time sudo ran, but it
was too many times. Instead, I'll just ask you this one time:

Can I use sudo?
[y/n] y
```

この段階でパスワードを聞かれるかもしれません。  
その場合、現在ログインしているユーザのパスワードを入力してください。

その後、以下のようなログがしばらく出続けます。  
数分程度かかると思うので、 `y/n` の質問には `y` で答えながらしばらく待ちましょう。

```
Yay! Thanks! Let's get going!

~~> Fixing any leftover Nix volume state
Before I try to install, I'll check for any existing Nix volume config
and ask for your permission to remove it (so that the installer can
start fresh). I'll also ask for permission to fix any issues I spot.

~~> Checking for artifacts of previous installs
Before I try to install, I'll check for signs Nix already is or has
been installed on this system.

---- Nix config report ---------------------------------------------------------
        Temp Dir:	/var/folders/xb/js_jbz516r94m8r8t8s8r48c0000gn/T/tmp.aGkVEjZbwT
        Nix Root:	/nix
     Build Users:	32
  Build Group ID:	350
Build Group Name:	nixbld

...(略)...
```

しばらくすると以下のような表示がされて出力が止まります。

```
Alright! We're done!
Try it! Open a new terminal, and type:

  $ nix-shell -p nix-info --run "nix-info -m"

Thank you for using this installer. If you have any feedback or need
help, don't hesitate:

You can open an issue at
https://github.com/NixOS/nix/issues/new?labels=installer&template=installer.md

Or get in touch with the community: https://nixos.org/community
```

最後に Enter を押せば実行終了となります。


#### 動作確認

動作確認をするために、さきほどの表示にあった通り新しいターミナルのウィンドウを開き以下のコマンドを実行します。  
※インストールを実行したタブはまだ Nix を取り込めていないので、新しいタブまたはウィンドウを作成してください。

```bash
nix-shell -p nix-info --run "nix-info -m"
```

出力：

```bash
$ nix-shell -p nix-info --run "nix-info -m"
these 5 paths will be fetched (0.04 MiB download, 0.20 MiB unpacked):
  /nix/store/kvx50ndpfcx73w39inrk63fnfi47wqwy-cctools-binutils-darwin-wrapper-1010.6
  /nix/store/9fbzrya8pqaw0lfhg9q0g3pscy2aw7kz-clang-wrapper-16.0.6
  /nix/store/k9nxqn481wyx3xwqff05arlfyy9gbj0j-expand-response-params
  /nix/store/laq2hijsy5102qxmhw2z42rafprbisgd-libSystem-B
  /nix/store/nxybyv1j7awpcb29v7dy25f88r716y23-stdenv-darwin
copying path '/nix/store/k9nxqn481wyx3xwqff05arlfyy9gbj0j-expand-response-params' from 'https://cache.nixos.org'...
copying path '/nix/store/laq2hijsy5102qxmhw2z42rafprbisgd-libSystem-B' from 'https://cache.nixos.org'...
copying path '/nix/store/kvx50ndpfcx73w39inrk63fnfi47wqwy-cctools-binutils-darwin-wrapper-1010.6' from 'https://cache.nixos.org'...
copying path '/nix/store/9fbzrya8pqaw0lfhg9q0g3pscy2aw7kz-clang-wrapper-16.0.6' from 'https://cache.nixos.org'...
copying path '/nix/store/nxybyv1j7awpcb29v7dy25f88r716y23-stdenv-darwin' from 'https://cache.nixos.org'...
 - system: `"aarch64-darwin"`
 - host os: `Darwin 24.3.0, macOS 15.3.1`
 - multi-user?: `yes`
 - sandbox: `no`
 - version: `nix-env (Nix) 2.24.13`
 - channels(root): `"nixpkgs"`
 - nixpkgs: `/nix/store/v79jbgwmxgiy8m01rhmj4yzn5y507z2c-source`
```

ここでは、 Nix パッケージマネージャの機能の一つ `nix-shell` コマンドを使っています。  
`nix-shell` は、何らかの Nix パッケージがインストールされた一時的なシェル環境を作成できるツールです。

各コマンドライン引数の意味は以下の通りです。

- `-p nix-info`： `nix-info` というパッケージ（**P**ackage）をインストールする
- `--run "nix-info -m"`： `nix-info` が入ったシェル環境で `nix-info -m` というコマンドを実行する

`--run` オプションを使わなければ、 `nix-info` がインストールされた状態でインタラクティブシェルに入ることができます。

```
$ nix-shell -p nix-info

[nix-shell:~]$ nix-info -h
nix-info - get high level info to help with debugging

Options:

 -m, --markdown   formatting for a GitHub issue
                  implies: --host-os, --sandbox

     --sandbox    include sandbox configuration
     --host-os    include host OS details

 -h, --help       show this message
 -d, --debug      debug mode
```

ところで、先ほど「パッケージがインストールされた一時的なシェル環境」と言いましたが、その意味するところは、 `nix-shell` を閉じると当該パッケージが利用できなくなるということです。

```bash
$ nix-shell -p cowsay
this path will be fetched (0.01 MiB download, 0.04 MiB unpacked):
  /nix/store/3cdrq8c0xbxqkg240n1k5xg9nxbc67s7-cowsay-3.8.3
copying path '/nix/store/3cdrq8c0xbxqkg240n1k5xg9nxbc67s7-cowsay-3.8.3' from 'https://cache.nixos.org'...

[nix-shell:~]$ cowsay 'Hello Nix!'
 ____________
< Hello Nix! >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

[nix-shell:~]$ which cowsay
/nix/store/3cdrq8c0xbxqkg240n1k5xg9nxbc67s7-cowsay-3.8.3/bin/cowsay

[nix-shell:~]$ exit
exit

$ which cowsay
cowsay not found
```

また、ここでは `-p` オプションによりコマンドラインでパッケージを指定していますが、 Nix 言語を使ってファイルで管理することもできます。  
これにより、開発しているプロジェクトごとにツールやそのバージョンを使い分け流ようなことが簡単に実現できます。

https://nix.dev/tutorials/first-steps/ad-hoc-shell-environments.html

さて、これで Nix パッケージマネージャの動作確認が完了しました。

個人的には、このように `nix-shell` でパッケージを気軽に試せるというだけでも Nix をインストールする価値は大いにあると考えています。  
Nix の手放せない機能の一つです。


#### `nix-shell` の出力について

`nix-shell` を実行した際の出力の冒頭は、シェル環境を作るのに必要なパッケージやファイルをダウンロード・設置している様子を示しています。  
Nix は以下のように「ハッシュ文字列＋パッケージ名＋バージョン」の三つでパッケージを区別（管理）します。  
これにより、一つのマシン上に複数バージョンの同一プログラムをインストールできたり、ビルドの再現性が高いなどの特長があります。

```
9fbzrya8pqaw0lfhg9q0g3pscy2aw7kz-clang-wrapper-16.0.6
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~ ^~~~~~
            hash                  package name  version
```

https://nix.dev/manual/nix/2.25/store/store-path

ここでは深く説明しませんが、これによる **ビルド再現性** や **依存完全性** などは Nix 固有の非常に有益な特性です。

https://nix.dev/manual/nix/2.24/


### ② nix-darwin

nix-darwin は、 Nix 言語を使って macOS の設定を行うためのシステムです。

設定可能な項目の例として以下が挙げられます。

- ユーザの作成
- 全ユーザ向けに共通でインストールするパッケージの指定
- フォントのインストール
- ネットワークの設定
- などなど

設定できる項目数は非常に膨大なので、ぜひマニュアルを読んでいただければと思います。

https://nix-darwin.github.io/nix-darwin/manual/index.html

また、 Home Mnaager をシステムに適用（インストール）する設定も後ほど nix-darwin　で行います。


#### インストール手順

GitHub の README に手順が書かれています。

https://github.com/nix-darwin/nix-darwin?tab=readme-ov-file#getting-started

インストール方法は二種類が用意されており、 *Nix Flakes* を使う方法と Channel を使う方法があります。  
Flakes はまだ実験的な機能ですが、基本的にはそちらで問題ないと思います。

以下のコマンドを順に実行します。

```
sudo mkdir -p /etc/nix-darwin
sudo chown "$(id -nu):$(id -ng)" /etc/nix-darwin
cd /etc/nix-darwin

nix flake init -t nix-darwin/master

sed -i '' "s/simple/$(scutil --get LocalHostName)/" flake.nix

nix --extra-experimental-features 'nix-command flakes' run nix-darwin/nix-darwin-24.11#darwin-rebuild -- switch

darwin-rebuild switch
```

:::note
2025/04/15 追記：

環境によっては、 `sudo chown $(id -nu):$(id -ng) /etc/nix-darwin` が失敗します。  
操作しているユーザ名またはそのグループの名前にスペースが含まれると chown の第一引数が壊れてしまうことが原因です。

上記では、公式ページのコマンドを編集して `"$(id -nu):$(id -ng)"` というふうにダブルクォートで囲うことでたいさくしていま
:::



`sudo mkdir` 〜 `sed` までは必要なファイル・ディレクトリを準備するものです。  
`nix --extra-(中略)... run` は、 nix-shell と似た要領で  `nix-darwin` を一時的に用意し、インストール処理を実行します。  

なお、ここでは 2024/11 リリースの 24.11 バージョンをインストールしています。  
半年ごと （５月、１１月）にリリースがあるので、みなさんは最新バージョンを確認して適宜読み替えてください。

さて、 `nix run` を実行すると以下のような出力が得られるはずです。

```
$ nix --extra-experimental-features 'nix-command flakes' run nix-darwin/24.11#darwin-rebuild -- switch
building the system configuration...
user defaults...
setting up user launchd services...
setting up /Applications/Nix Apps...
setting up pam...
applying patches...
setting up /etc...
system defaults...
setting up launchd services...
creating service org.nixos.activate-system
reloading service org.nixos.nix-daemon
reloading nix-daemon...
waiting for nix-daemon
waiting for nix-daemon
configuring networking...
configuring power...
setting up /Library/Fonts/Nix Fonts...
setting nvram variables...
```

launchd デーモンの設定や `/etc/` 等のディレクトリのセットアップ、フォントのインストールなどを行っていることが読み取れます。  
まだ何も設定を投入していないので特に画面上に変化はないはずですが、ひとまず正常に nix-darwin がインストールできました。

インストールが済むと、次回以降は直接 `darwin-rebuild` コマンドを実行できます。

```bash
darwin-rebuild switch
```


#### 設定を投入する

nix-darwin の役割は、 Nix 言語を使ってシステムの各種設定を投入できることでした。  
実際に幾つか設定をしてみようと思います。

お好きなエディタを使って、設定ファイルである `/etc/nix-darwin/flake.nix` を開きます。

デフォルトでは以下のような内容になっているはずです。

```/etc/nix-darwin/flake.nix
{
  description = "Example nix-darwin system flake";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-24.11-darwin";
    nix-darwin.url = "github:nix-darwin/nix-darwin/nix-darwin-24.11";
    nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs = inputs@{ self, nix-darwin, nixpkgs }:
  let
    configuration = { pkgs, ... }: {
      # List packages installed in system profile. To search by name, run:
      # $ nix-env -qaP | grep wget
      environment.systemPackages =
        [ pkgs.vim
        ];

      # Necessary for using flakes on this system.
      nix.settings.experimental-features = "nix-command flakes";

      # Enable alternative shell support in nix-darwin.
      # programs.fish.enable = true;

      # Set Git commit hash for darwin-version.
      system.configurationRevision = self.rev or self.dirtyRev or null;

      # Used for backwards compatibility, please read the changelog before changing.
      # $ darwin-rebuild changelog
      system.stateVersion = 5;

      # The platform the configuration will be used on.
      nixpkgs.hostPlatform = "aarch64-darwin";
    };
  in
  {
    # Build darwin flake using:
    # $ darwin-rebuild build --flake .#ホスト名
    darwinConfigurations."ホスト名" = nix-darwin.lib.darwinSystem {
      modules = [ configuration ];
    };
  };
}
```

大きく三つのパートに分解できます。

- `description`：この flake.nix ファイルの説明文
    - flake.nix は、 nix-darwin だけでなく Nix パッケージマネージャによるプロジェクト管理などにも使われるので、このファイルが `nix-darwin` の設定を含むことを説明しています
    - ちなみに `nix-darwin` の設定や NixOS の設定、開発環境の定義などを一つの flake.nix にまとめることもできます
- `inputs`：この Flake に加えて外部から取得する入力データ
    - ここでは `nixpkgs` と `nix-darwin` の二つが指定されています
    - 大抵の場合 GitHub から取得されます
    - ここで指定した入力は、ビルド時に "固定" されます
        - `flake.lock` ファイルに、ビルドした時点の Git コミットハッシュやデータのハッシュ値が記録されます
        - それらの値を参照することで、必ず全く同じ入力データを得られるようになっています
        - こうして入力を "固定" することで、非常に高い再現性でビルドできるようになっています
- `outputs`；入力データを使って定義した、 nix-darwin の設定本体
    - `let-in` 式により、変数の定義パート（`configuration = ...`）と出力パート (`{ darwin Configuration = ...; }`）の二つで構成されています
    - 変数パートで定義された `configuration` の値が出力パートの `moudles` として使用されており、つまり `configuration` の値が実際の設定本体に当たります

`configuration` の値を詳しくみると、設定されている項目はざっくり二点だけですね。

- `environment.systemPackages`
    - この flake.nix による設定を適用することで、システム全体にインストールされるパッケージのリスト
    - `vim` パッケージのみが含まれています
- `nix.settings.experimental-features`
    - Nix　パッケージマネージャの追加設定をしています
    - Flake および `nix xxx` 系コマンドはまだ実験的機能なので、明示的に許可する設定をしています
    - さきほどの `nix run` を実行した際にも指定していましたね

それ以外の部分はプラットフォーム（OS + CPU アーキテクチャ）の指定や nix-darwin のバージョンの指定などです。  
編集することは多くないはずなので一旦置いておきましょう。

その他、 Flake の構成要素や読み方・書き方については、冒頭で紹介した筆者の別記事でも簡単に触れているほか、 Nix の公式ページ、 NixOS Wiki、 Asahi さんの記事でも説明されています。

https://zenn.dev/kino_ma/articles/f2a4df384b91a4

https://nix.dev/concepts/flakes.html

https://nixos.wiki/wiki/Flakes

https://zenn.dev/asa1984/books/nix-introduction/viewer/11-flakes

皆さんはこれらのページや nix-darwin の [オプション一覧](https://nix-darwin.github.io/nix-darwin/manual/index.html) を参照してお好みの設定を作っていくと良いでしょう。

参考までに、筆者が実際に使っている設定を一部抜粋しておきます。

https://github.com/kino-ma/dotfiles/blob/6d5d380f826dfc019b9185012e189b674c833a58/platforms/darwin-common.nix

```nix
{ pkgs, ... }:

let

  scroll-reverser = pkgs.callPackage ../pkgs/scroll-reverser { };

in
{
  environment.systemPackages = [
    scroll-reverser
  ];

  nix.settings.experimental-features = "nix-command flakes";

  # Zsh をシステム全体で有効化する
  programs.zsh.enable = true; # default shell on catalina

  # 追加フォントをインストール
  fonts.packages = [ pkgs.nerdfonts pkgs.monaspace ];

  # Nix パッケージマネージャを使うにあたり、非フリーまたは broken なパッケージも許容する
  nixpkgs.config = {
    allowUnfree = true;
    allowBroken = true;
  };

  system.defaults.dock.orientation = "left";

  system.defaults.screencapture.location = "$HOME/Documents/screenshots";
}
```

実はたいていの設定は後述する Home Manager で行ってしまっているので、ここではたいした設定をしていません。  
特筆すべき点があるとしたら以下でしょうか。

- [Scroll Reverser](https://pilotmoon.com/scrollreverser/) というパッケージを追加しています
    - マウスとトラックパッドとでスクロール方向を逆転するためのツールです
    - Nixpkgs （Nix 公式のパッケージストア）では提供されていないので、別ファイル（[`pkgs/scroll-reverser/default.nix`](https://github.com/kino-ma/dotfiles/blob/master/pkgs/scroll-reverser/default.nix) にて自分でビルド・インストール方法を定義しています
- 追加フォントをインストールしています
    - NerdFonts と Monaspace 二つの追加フォントを指定しています


### ③ Home Manager

最後に、 Home Manager をインストールおよび設定します。

[Home Manager](https://github.com/nix-community/home-manager) は、 Nix エコシステムに乗っかることで便利にユーザ環境を設定できるシステムです。

代表的な（i.e., 筆者がよく使う）機能に以下があります。

- Nixpkgs からのパッケージのインストール
- インストールしたパッケージ個別の設定
    - Git, Neovim, ターミナル等
- `$HOME` 以下のファイル管理

簡単に言えば、従来各開発者が `dotfiles` で管理していたような設定手順を Nix 言語で管理できるというものです。

宣言的に定義することができ、かつ Nix パッケージマネージャのビルド再現性の恩恵を受けられるため、設定の変更や新規環境への移行が非常に簡単です。

といっても、 nix-darwin のインストールが済んでいれば特別な作業はほとんど必要ありません。

公式ドキュメントには Nix Flakes を使ってインストールする方法が説明されており、この方法なら `flake.nix` に inputs と outputs を追加するだけでインストールおよび設定が完了します。

https://nix-community.github.io/home-manager/#ch-nix-flakes

具体的に変更するのは三点です：

- inputs に `home-manager` を追加する
- configuration に `home-manager.users."ユーザ名"` オプションを追加し、値に `home.nix` と指定する
- darwinConfiguration の modules に home-manager の module とちょっとした設定を入れる

```diff_nix
 {
   description = "Example nix-darwin system flake";

   inputs = {
     nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-24.11-darwin";
     nix-darwin.url = "github:nix-darwin/nix-darwin/nix-darwin-24.11";
     nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
+    home-manager.url = "github:nix-community/home-manager";
+    home-manager.inputs.nixpkgs.follows = "nixpkgs";
   };

   outputs = inputs@{ self, nix-darwin, nixpkgs }:
   let
     configuration = { pkgs, ... }: {
       # List packages installed in system profile. To search by name, run:
       # $ nix-env -qaP | grep wget
       environment.systemPackages =
         [ pkgs.vim
         ];

       # Necessary for using flakes on this system.
       nix.settings.experimental-features = "nix-command flakes";

       # Enable alternative shell support in nix-darwin.
       # programs.fish.enable = true;

       # Set Git commit hash for darwin-version.
       system.configurationRevision = self.rev or self.dirtyRev or null;

       # Used for backwards compatibility, please read the changelog before changing.
       # $ darwin-rebuild changelog
       system.stateVersion = 5;

       # The platform the configuration will be used on.
       nixpkgs.hostPlatform = "aarch64-darwin";
+
+      home-manager.users."ユーザ名" = import ./home.nix;
     };
   in
   {
     # Build darwin flake using:
     # $ darwin-rebuild build --flake .#domremy
     darwinConfigurations."domremy" = nix-darwin.lib.darwinSystem {
-      modules = [ configuration ];
+      modules =
+      [ configuration
+        home-manager.darwinModules.home-manager
+        {
+          home-manager.useGlobalPkgs = true;
+          home-manager.useUserPackages = true;
+        }
+      ];
     };
   };
 }
 ```

そして、 `home-manager.users."ユーザ名"` に指定した `home.nix` というファイルを作成します。

以下に、公式の [config 例](https://nix-community.github.io/home-manager/index.xhtml#sec-usage-configuration) や筆者のコンフィグをもとに作成したシンプルな `home.nix` を示します。

```nix:home.nix
{ config, pkgs, ... }:

{
  home.username = "ユーザ名";
  home.homeDirectory = "/Users/ユーザ名";

  home.programs.git = {
    enable = true;
    userName = "GitHub アカウント名";
    userEmail = "GitHub メールアドレス";
    ignores = [ ".DS_Store" ];
  };

  home.stateVersion = "24.11";

  programs.home-manager.enable = true;
}
```

ここでは、試しに Git のユーザアカウントとグローバルの gitignore の設定を投入してみました。  
この通りシンプルな記述で設定可能です。

Home Manager で設定可能な項目は nix-darwin 同様膨大であり、 Git 以外にも非常に多数のソフトウェアをインストール・設定することができます。  
ぜひオプション一覧を見ていただき、あなたの普段使うソフトウェアを見つけてみてください。

https://nix-community.github.io/home-manager/options.xhtml

また、筆者の Home Manager 設定は以下にあります。  
筆者は Git の他に zsh, GnuPG, NeoVim, ssh, WezTerm, direnv, bat, eza, fzf, ripgrep, tmux の設定をしています。

https://github.com/kino-ma/dotfiles/tree/6d5d380f826dfc019b9185012e189b674c833a58/home


## その後の使い方

さて、これでインストールや初期設定は完了しました。

あとは皆さんのお気に入りのソフトウェアをインストールしたり設定したり、新たなホストに移植したりするだけです。

具体的にどんなパッケージやシステム設定項目があるかは、膨大すぎて列挙できません。  
ぜひ、以下の検索サイトやマニュアルを見てお好みの環境を作り上げてください。


### Nixpkgs

https://search.nixos.org/packages

Nix パッケージマネージャが公式で提供するパッケージを検索できます。

2025/04 現在 120,000 以上のパッケージが提供されているようで、これは apt などより圧倒的に多数です（具体的な数字（の調べ方）は忘れました）。

それらのパッケージは nix-darwin の `systemPackages`、 Home Manager の各ユーザの `home.packages`、 `nix-shell` で利用できます。

また、公式の Nixpkgs に登録されていないソフトウェアであっても、自分で Nix パッケージ化することができます。  
ここでは詳しいやり方には触れませんが、 Nix 言語の読み・書き方がわかったら以下が参考になると思います。

- *derivation* 作成方法についての公式ドキュメント
    - ① https://nixos.org/guides/nix-pills/06-our-first-derivation
    - ② https://nixos.org/guides/nix-pills/07-working-derivation
- Nixpkgs 公式のパッケージ群
    - たとえば GNU `hello` https://github.com/NixOS/nixpkgs/blob/nixos-24.11/pkgs/by-name/he/hello/package.nix#L47
- 筆者が dotfiles で macOS 向けソフトウェアを Nix パッケージ化しているもの
    - Scroll Reverser https://github.com/kino-ma/dotfiles/blob/master/pkgs/scroll-reverser/default.nix


### nix-darwin

https://nix-darwin.github.io/nix-darwin/manual/index.html

nix-darwin の設定項目を一覧で見られます。

超〜長いので全部は読みきれないと思います。  
個人的には、以下を軽く眺めると有益そうなオプションが見つかるんじゃないかと思います。[^homebrew]

[^homebrew]: 一覧を眺めていると、 `homebrew` という項目があるのに気づくかもしれません。 Nix があれば Homebrew なんていらないので無視してください

- `environment`：システム環境系
- `networking`：ネットワーク系の設定
- `nix`： Nix パッケージマネージャの設定
- `nixpkgs`： Nixpkgs の設定
- `system`：システム環境設定.app で変更できる項目いろいろ
- `users`： macOS 上のユーザ管理

ほかにも `programs` は便利そうです。  
一方で大体がシェル関連で、同じことが  Home Manager で大体済む気もする、重要度はそんなに高くないと思っています。

ちなみに、非公式ですがオプション検索サイトもあります。

https://searchix.alanpearce.eu/options/darwin/search


### Home Manager

https://nix-community.github.io/home-manager/options.xhtml

Home Manager のオプション一覧です。

超々膨大です。読み切るのは実質不可能だと思います。

こちらは nix-darwin とは異なり、システム全体というよりユーザ個別のパッケージインストールしたり設定したりするためのオプションが提供されています。  
例としては先ほど紹介した Git の設定や、 Zsh、 Tmux の設定などができます。

そういった使いたいパッケージを狙い撃ちして、以下の検索サイトを使うのがいいと思います。

https://home-manager-options.extranix.com/

たとえば zsh なら、通常 zshrc で設定する項目を Nix で代替することができます。  
（厳密には、こうして Nix で設定された項目を zshrc に変換してホームディレクトリに配置してくれます。）

![Screenshot 2025-04-12 at 11.14.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508344/0e5e781a-ea10-4949-beaa-0613e0cf2cbc.png)

.zshrc や .vimrc など、 dotfiles と呼ばれる従来の設定を Nix （Home Manager）に移行する手順については他の方も記事にしてくださっています。  
いくつか参考になりそうなページを挙げさせていただくので、こちらを参照してみるのもよいでしょう。

https://blog.tomoyukim.net/entry/nix-home-manager/

https://zenn.dev/airrnot1106/scraps/20e6a33574229f

https://blog.ryota-ka.me/posts/2021/12/31/home-manager


### Nix 全般

また、 nix-darwin や Home Manager に限らず、 Nix えこしsを使うにあたっては他の人の Nix ファイルを参考にするのが非常に重要です。

というのも、 Nix はその再現性という特長もあって、一度完成したコンフィグ（環境）について記事化するモチベーションが生まれにくい感覚があります。  
実際、筆者はもう二、三年 Nix を使っていますが、ちゃんとゼロからインストール方法の記事を書いたのは初めてです。[^hukyo]

[^hukyo]: 所属組織が変わったので布教目的で書き始めました

純粋関数型言語である Nix は、コード（つまり設定）の一部だけ引っ張ってくることも容易です。  
以下の筆者のリポジトリを含め、 GitHub 上で Nix ファイルを漁ると設定が捗るでしょう。

筆者の環境設定（人に見せられるレベルではちゃんとメンテしてませんが……。）：

https://github.com/kino-ma/dotfiles


## まとめ

この記事では、 macOS に Nix エコシステムをセットアップする方法を紹介しました。

冒頭のモチベーションの節で説明した通り、 Nix エコシステムを使うとシステム環境の再現が非常に容易です。  
実際筆者は先日所属組織が変わり新たな PC 環境を作り直しましたが、開発に必要なソフトウェアのセットアップは、本記事にあるインストール手順ののち以前の Nix ファイルを読み込むだけで完了しました。

ほかにも *ロールバック* 機能、 *プロファイル* 機能など本記事で紹介しなかった有益な機能がたくさんあります。  
興味のある方はぜひ調べてみてください。

ここまで読んでいただきありがとうございました。  
この記事で Nix ユーザが増え、日本語情報が充実することでさらにユーザが増えますように。