<divclass="toc"><p><strong>Table of Contents</strong></p><dlclass="toc"><dt><spanclass="preface"><ahref="index.xhtml#preface">Preface</a></span></dt><dt><spanclass="part"><ahref="index.xhtml#ch-introduction">Introduction to Home Manager</a></span></dt><dt><spanclass="part"><ahref="index.xhtml#ch-installation">Installing Home Manager</a></span></dt><dd><dl><dt><spanclass="section"><ahref="index.xhtml#sec-install-standalone">Standalone installation</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-install-nixos-module">NixOS module</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-install-nix-darwin-module">nix-darwin module</a></span></dt></dl></dd><dt><spanclass="part"><ahref="index.xhtml#ch-usage">Using Home Manager</a></span></dt><dd><dl><dt><spanclass="section"><ahref="index.xhtml#sec-usage-configuration">Configuration Example</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-usage-rollbacks">Rollbacks</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-usage-dotfiles">Keeping your ~ safe from harm</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-usage-graphical">Graphical services</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-usage-gpu-non-nixos">GPU on non-NixOS systems</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-updating">Updating</a></span></dt></dl></dd><dt><spanclass="part"><ahref="index.xhtml#ch-nix-flakes">Nix Flakes</a></span></dt><dd><dl><dt><spanclass="section"><ahref="index.xhtml#sec-flakes-prerequisites">Prerequisites</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-flakes-standalone">Standalone setup</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-flakes-nixos-module">NixOS module</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-flakes-nix-darwin-module">nix-darwin module</a></span></dt></dl></dd><dt><spanclass="part"><ahref="index.xhtml#ch-writing-modules">Writing Home Manager Modules</a></span></dt><dd><dl><dt><spanclass="section"><ahref="index.xhtml#sec-option-types">Option Types</a></span></dt></dl></dd><dt><spanclass="part"><ahref="index.xhtml#ch-contributing">Contributing</a></span></dt><dd><dl><dt><spanclass="section"><ahref="index.xhtml#sec-contrib-getting-started">Getting started</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-guidelines">Guidelines</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-news">News</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-tests">Tests</a></span></dt></dl></dd><dt><spanclass="part"><ahref="index.xhtml#ch-3rd-party">Third-Party Tools and Extensions</a></span></dt><dd><dl><dt><spanclass="section"><ahref="index.xhtml#sec-3rd-party-module-collections">Module Collections</a></span></dt></dl></dd><dt><spanclass="part"><ahref="index.xhtml#ch-faq">Frequently Asked Questions (FAQ)</a></span></dt><dd><dl><dt><spanclass="section"><ahref="index.xhtml#_why_is_there_a_collision_error_when_switching_generation">Why is there a collision error when switching generation?</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#_why_are_the_session_variables_not_set">Why are the session variables not set?</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#_how_to_set_up_a_configuration_for_multiple_users_machines">How to set up a configuration for multiple users/machines?</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#_why_do_i_get_an_error_message_about_literal_ca_desrt_dconf_literal_or_literal_dconf_service_literal">Why do I get an error message about <codeclass="literal">ca.desrt.dconf</code> or <codeclass="literal">dconf.service</code>?</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#_how_do_i_install_packages_from_nixpkgs_unstable">How do I install packages from Nixpkgs unstable?</a></span></dt><dt><spanclass="section"><ahref="index.xht
<divclass="preface"><divclass="titlepage"><div><div><h1id="preface"class="title">Preface </h1></div></div></div><p>This manual will eventually describe how to install, use, and extend Home
hosted by <aclass="link"href="https://oftc.net/"target="_top">OFTC</a>.
There is also a <aclass="link"href="https://matrix.to/#/%23hm:rycee.net"target="_top">Matrix room</a>,
which is bridged to the IRC channel.
If your problem is caused by a bug in Home Manager then it should
be reported on the
<aclass="link"href="https://github.com/nix-community/home-manager/issues"target="_top">Home Manager issue tracker</a>.</p><divclass="note"><h3class="title">Note</h3><p>Commands prefixed with <codeclass="literal">$ sudo</code> have to be run as root, either
requiring to login as root user or temporarily switching to it using
<codeclass="literal">sudo</code> for example.</p></div>
</div><divclass="part"><divclass="titlepage"><div><div><h1id="ch-introduction"class="title">Introduction to Home Manager </h1></div></div></div><divclass="partintro"><p>Home Manager is a <aclass="link"href="https://nix.dev/"target="_top">Nix</a>-powered tool for reproducible management of the contents of users’ home directories.
This includes programs, configuration files, environment variables and, well… arbitrary files.
The following example snippet of Nix code:</p><pre><codeclass="programlisting nix">programs.git = {
enable = true;
userEmail = "joe@example.org";
userName = "joe";
};
</code></pre><p>would make available to a user the <codeclass="literal">git</code> executable and man pages and a configuration file <codeclass="literal">~/.config/git/config</code>:</p><pre><codeclass="programlisting ini">[user]
email = "joe@example.org"
name = "joe"
</code></pre><p>Since Home Manager is implemented in Nix, it provides several benefits:</p><divclass="itemizedlist"><ulclass="itemizedlist compact"style="list-style-type: disc;"><liclass="listitem"><p>Contents are reproducible — a home will be the exact same every time it is built, unless of course, an intentional change is made.
This also means you can have the exact same home on different hosts.</p></li><liclass="listitem"><p>Significantly faster and more powerful than various backup strategies.</p></li><liclass="listitem"><p>Unlike “dotfiles” repositories, Home Manager supports specifying programs, as well as their configurations.</p></li><liclass="listitem"><p>Supported by <aclass="link"href="http://cache.nixos.org/"target="_top">http://cache.nixos.org/</a>, so that you don’t have to build from source.</p></li><liclass="listitem"><p>If you do want to build some programs from source, there is hardly a tool more useful than Nix for that, and the build instructions can be neatly integrated in your Home Manager usage.</p></li><liclass="listitem"><p>Infinitely composable, so that values in different configuration files and build instructions can share a source of truth.</p></li><liclass="listitem"><p>Connects you with the <aclass="link"href="https://repology.org/repositories/statistics/total"target="_top">most extensive</a> and <aclass="link"href="https://repology.org/repositories/statistics/newest"target="_top">most up-to-date</a> software package repository on earth, <aclass="link"href="https://github.com/NixOS/nixpkgs"target="_top">Nixpkgs</a>.</p></li></ul></div></div>
</div><divclass="part"><divclass="titlepage"><div><div><h1id="ch-installation"class="title">Installing Home Manager </h1></div></div></div><divclass="partintro"><p>Home Manager can be used in three primary ways:</p><divclass="orderedlist"><olclass="orderedlist "type="1"><liclass="listitem"><p>Using the standalone <codeclass="literal">home-manager</code> tool. For platforms other than
NixOS and Darwin, this is the only available choice. It is also
recommended for people on NixOS or Darwin that want to manage their
home directory independently of the system as a whole. See
<aclass="link"href="index.xhtml#sec-install-standalone"title="Standalone installation">Standalone installation</a> for instructions
on how to perform this installation.</p></li><liclass="listitem"><p>As a module within a NixOS system configuration. This allows the
user profiles to be built together with the system when running
<codeclass="literal">nixos-rebuild</code>. See <aclass="link"href="index.xhtml#sec-install-nixos-module"title="NixOS module">NixOS module</a> for a
description of this setup.</p></li><liclass="listitem"><p>As a module within a
<aclass="link"href="https://github.com/LnL7/nix-darwin/"target="_top">nix-darwin</a> system
configuration. This allows the user profiles to be built together
with the system when running <codeclass="literal">darwin-rebuild</code>. See <aclass="link"href="index.xhtml#sec-install-nix-darwin-module"title="nix-darwin module">nix-darwin
module</a> for a description of this
setup.</p></li></ol></div><divclass="note"><h3class="title">Note</h3><p>In this chapter we describe how to install Home Manager in the standard
in <aclass="link"href="index.xhtml#ch-nix-flakes"title="Nix Flakes">nix flakes</a>.</p></div><divclass="toc"><p><strong>Table of Contents</strong></p><dlclass="toc"><dt><spanclass="section"><ahref="index.xhtml#sec-install-standalone">Standalone installation</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-install-nixos-module">NixOS module</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-install-nix-darwin-module">nix-darwin module</a></span></dt></dl></div></div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-install-standalone"class="title"style="clear: both">Standalone installation </h2></div></div></div><divclass="orderedlist"><olclass="orderedlist "type="1"><liclass="listitem"><p>Make sure you have a working Nix installation. Specifically, make
system option.</p></li><liclass="listitem"><p>Add the appropriate Home Manager channel. If you are following
Nixpkgs master or an unstable channel you can run</p><pre><codeclass="programlisting shell">$ nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
</code></pre><p>and if you follow a Nixpkgs version 24.11 channel you can run</p><pre><codeclass="programlisting shell">$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.11.tar.gz home-manager
</code></pre></li><liclass="listitem"><p>Run the Home Manager installation command and create the first Home
Manager generation:</p><pre><codeclass="programlisting shell">$ nix-shell '<home-manager>' -A install
</code></pre><p>Once finished, Home Manager should be active and available in your
user environment.</p></li><liclass="listitem"><p>If you do not plan on having Home Manager manage your shell
configuration then you must source the</p><pre><codeclass="programlisting bash">$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh
</code></pre><p>file in your shell configuration. Alternatively source</p><pre><codeclass="programlisting bash">/etc/profiles/per-user/$USER/etc/profile.d/hm-session-vars.sh
</code></pre><p>when managing home configuration together with system configuration.</p><p>This file can be sourced directly by POSIX.2-like shells such as
<aclass="link"href="https://www.gnu.org/software/bash/"target="_top">Bash</a> or <aclass="link"href="http://zsh.sourceforge.net/"target="_top">Z
<aclass="link"href="https://github.com/oh-my-fish/plugin-foreign-env"target="_top">foreign-env</a> or
<aclass="link"href="https://github.com/bouk/babelfish"target="_top">babelfish</a>.</p><p>For example, if you use Bash then add</p><pre><codeclass="programlisting bash">. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
</code></pre><p>to your <codeclass="literal">~/.profile</code> file.</p></li></ol></div><p>If instead of using channels you want to run Home Manager from a Git
path to the repository.</p><p>Once installed you can see <aclass="link"href="index.xhtml#ch-usage"title="Using Home Manager">Using Home Manager</a> for a more detailed
description of Home Manager and how to use it.</p>
</div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-install-nixos-module"class="title"style="clear: both">NixOS module </h2></div></div></div><p>Home Manager provides a NixOS module that allows you to prepare user
environments directly from the system configuration file, which often is
more convenient than using the <codeclass="literal">home-manager</code> tool. It also opens up
additional possibilities, for example, to automatically configure user
environments in NixOS declarative containers or on systems deployed
through NixOps.</p><p>To make the NixOS module available for use you must <codeclass="literal">import</code> it into
your system configuration. This is most conveniently done by adding a
Home Manager channel to the root user. For example, if you are following
Nixpkgs master or an unstable channel, you can run</p><pre><codeclass="programlisting shell">$ sudo nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
</code></pre><p>and if you follow a Nixpkgs version 24.11 channel, you can run</p><pre><codeclass="programlisting shell">$ sudo nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.11.tar.gz home-manager
</code></pre><p>It is then possible to add</p><pre><codeclass="programlisting nix">imports = [ <home-manager/nixos> ];
</code></pre><p>to your system <codeclass="literal">configuration.nix</code> file, which will introduce a new
NixOS option called <codeclass="literal">home-manager.users</code> whose type is an attribute set
that maps user names to Home Manager configurations.</p><p>For example, a NixOS configuration may include the lines</p><pre><codeclass="programlisting nix">users.users.eve.isNormalUser = true;
home-manager.users.eve = { pkgs, ... }: {
home.packages = [ pkgs.atool pkgs.httpie ];
programs.bash.enable = true;
# The state version is required and should stay at the version you
</code></pre><p>and after a <codeclass="literal">sudo nixos-rebuild switch</code> the user eve’s environment
should include a basic Bash configuration and the packages atool and
httpie.</p><divclass="note"><h3class="title">Note</h3><p>If <codeclass="literal">nixos-rebuild switch</code> does not result in the environment you expect,
you can take a look at the output of the Home Manager activation script
output using</p><pre><codeclass="programlisting shell">$ systemctl status "home-manager-$USER.service"
</code></pre></div><p>If you do not plan on having Home Manager manage your shell
configuration then you must add either</p><pre><codeclass="programlisting bash">. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
<aclass="link"href="https://github.com/oh-my-fish/plugin-foreign-env"target="_top">foreign-env</a> or
<aclass="link"href="https://github.com/bouk/babelfish"target="_top">babelfish</a>.</p><divclass="note"><h3class="title">Note</h3><p>By default packages will be installed to <codeclass="literal">$HOME/.nix-profile</code> but they
can be installed to <codeclass="literal">/etc/profiles</code> if</p><pre><codeclass="programlisting nix">home-manager.useUserPackages = true;
</code></pre><p>is added to the system configuration. This is necessary if, for example,
you wish to use <codeclass="literal">nixos-rebuild build-vm</code>. This option may become the
default value in the future.</p></div><divclass="note"><h3class="title">Note</h3><p>By default, Home Manager uses a private <codeclass="literal">pkgs</code> instance that is
configured via the <codeclass="literal">home-manager.users.<name>.nixpkgs</code> options. To
instead use the global <codeclass="literal">pkgs</code> that is configured via the system level
</code></pre><p>This saves an extra Nixpkgs evaluation, adds consistency, and removes
the dependency on <codeclass="literal">NIX_PATH</code>, which is otherwise used for importing
Nixpkgs.</p></div><divclass="note"><h3class="title">Note</h3><p>Home Manager will pass <codeclass="literal">osConfig</code> as a module argument to any modules
you create. This contains the system’s NixOS configuration.</p><pre><codeclass="programlisting nix">{ lib, pkgs, osConfig, ... }:
</code></pre></div><p>Once installed you can see <aclass="link"href="index.xhtml#ch-usage"title="Using Home Manager">Using Home Manager</a> for a more detailed
description of Home Manager and how to use it.</p>
</div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-install-nix-darwin-module"class="title"style="clear: both">nix-darwin module </h2></div></div></div><p>Home Manager provides a module that allows you to prepare user
which often is more convenient than using the <codeclass="literal">home-manager</code> tool.</p><p>To make the NixOS module available for use you must <codeclass="literal">import</code> it into
your system configuration. This is most conveniently done by adding a
Home Manager channel. For example, if you are following Nixpkgs master
or an unstable channel, you can run</p><pre><codeclass="programlisting shell">$ nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
</code></pre><p>and if you follow a Nixpkgs version 24.11 channel, you can run</p><pre><codeclass="programlisting shell">$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-24.11.tar.gz home-manager
</code></pre><p>It is then possible to add</p><pre><codeclass="programlisting nix">imports = [ <home-manager/nix-darwin> ];
</code></pre><p>to your nix-darwin <codeclass="literal">configuration.nix</code> file, which will introduce a new
NixOS option called <codeclass="literal">home-manager</code> whose type is an attribute set that
maps user names to Home Manager configurations.</p><p>For example, a nix-darwin configuration may include the lines</p><pre><codeclass="programlisting nix">users.users.eve = {
<aclass="link"href="https://github.com/oh-my-fish/plugin-foreign-env"target="_top">foreign-env</a> or
<aclass="link"href="https://github.com/bouk/babelfish"target="_top">babelfish</a>.</p><divclass="note"><h3class="title">Note</h3><p>By default user packages will not be ignored in favor of
<codeclass="literal">environment.systemPackages</code>, but they will be installed to
</code></pre><p>is added to the nix-darwin configuration. This option may become the
default value in the future.</p></div><divclass="note"><h3class="title">Note</h3><p>By default, Home Manager uses a private <codeclass="literal">pkgs</code> instance that is
configured via the <codeclass="literal">home-manager.users.<name>.nixpkgs</code> options. To
instead use the global <codeclass="literal">pkgs</code> that is configured via the system level
</code></pre><p>This saves an extra Nixpkgs evaluation, adds consistency, and removes
the dependency on <codeclass="literal">NIX_PATH</code>, which is otherwise used for importing
Nixpkgs.</p></div><divclass="note"><h3class="title">Note</h3><p>Home Manager will pass <codeclass="literal">osConfig</code> as a module argument to any modules
you create. This contains the system’s nix-darwin configuration.</p><pre><codeclass="programlisting nix">{ lib, pkgs, osConfig, ... }:
</code></pre></div><p>Once installed you can see <aclass="link"href="index.xhtml#ch-usage"title="Using Home Manager">Using Home Manager</a> for a more detailed
description of Home Manager and how to use it.</p>
</div><divclass="part"><divclass="titlepage"><div><div><h1id="ch-usage"class="title">Using Home Manager </h1></div></div></div><divclass="partintro"><p>Your use of Home Manager is centered around the configuration file,
which is typically found at <codeclass="literal">~/.config/home-manager/home.nix</code> in the
standard installation or <codeclass="literal">~/.config/home-manager/flake.nix</code> in a Nix
flake based installation.</p><divclass="note"><h3class="title">Note</h3><p>The default configuration used to be placed in <codeclass="literal">~/.config/nixpkgs</code>¸ so
you may see references to that elsewhere. The old directory still works
but Home Manager will print a warning message when used.</p></div><p>This configuration file can be <spanclass="emphasis"><em>built</em></span> and <spanclass="emphasis"><em>activated</em></span>.</p><p>Building a configuration produces a directory in the Nix store that
contains all files and programs that should be available in your home
directory and Nix user profile, respectively. The build step also checks
that the configuration is valid and it will fail with an error if you,
for example, assign a value to an option that does not exist or assign a
value of the wrong type. Some modules also have custom assertions that
perform more detailed, module specific, checks.</p><p>Concretely, if your configuration contains</p><pre><codeclass="programlisting nix">programs.emacs.enable = "yes";
</code></pre><p>then building it, for example using <codeclass="literal">home-manager build</code>, will result in
an error message saying something like</p><pre><codeclass="programlisting console">$ home-manager build
error: A definition for option `programs.emacs.enable' is not of type `boolean'. Definition values:
- In `/home/jdoe/.config/home-manager/home.nix': "yes"
(use '--show-trace' to show detailed location information)
</code></pre><p>The message indicates that you must provide a Boolean value for this
option, that is, either <codeclass="literal">true</code> or <codeclass="literal">false</code>. The documentation of each
<aclass="link"href="options.xhtml"title="AppendixA.Home Manager Configuration Options">Home Manager Configuration Options</a> or directly in the terminal by running</p><pre><codeclass="programlisting shell">man home-configuration.nix
command performs a combined build and activation.</p><divclass="toc"><p><strong>Table of Contents</strong></p><dlclass="toc"><dt><spanclass="section"><ahref="index.xhtml#sec-usage-configuration">Configuration Example</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-usage-rollbacks">Rollbacks</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-usage-dotfiles">Keeping your ~ safe from harm</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-usage-graphical">Graphical services</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-usage-gpu-non-nixos">GPU on non-NixOS systems</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-updating">Updating</a></span></dt></dl></div></div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-usage-configuration"class="title"style="clear: both">Configuration Example </h2></div></div></div><p>A fresh install of Home Manager will generate a minimal
</code></pre><p>You can use this as a base for your further configurations.</p><divclass="note"><h3class="title">Note</h3><p>If you are not very familiar with the Nix language and NixOS modules
then it is encouraged to start with small and simple changes. As you
learn you can gradually grow the configuration with confidence.</p></div><p>As an example, let us expand the initial configuration file to also
install the htop and fortune packages, install Emacs with a few extra
packages available, and enable the user gpg-agent service.</p><p>To satisfy the above setup we should elaborate the <codeclass="literal">home.nix</code> file as
</code></pre><divclass="itemizedlist"><ulclass="itemizedlist "style="list-style-type: disc;"><liclass="listitem"><p>Nixpkgs packages can be installed to the user profile using
<aclass="link"href="options.xhtml#opt-home.packages">home.packages</a>.</p></li><liclass="listitem"><p>The option names of a program module typically start with
<codeclass="literal">programs.<package name></code>.</p></li><liclass="listitem"><p>Similarly, for a service module, the names start with
<codeclass="literal">services.<package name></code>. Note in some cases a package has both
programs <spanclass="emphasis"><em>and</em></span> service options – Emacs is such an example.</p></li></ul></div><p>To activate this configuration you can run</p><pre><codeclass="programlisting shell">home-manager switch
</code></pre><p>or if you are not feeling so lucky,</p><pre><codeclass="programlisting shell">home-manager build
</code></pre><p>which will create a <codeclass="literal">result</code> link to a directory containing an
activation script and the generated home directory files.</p>
</div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-usage-rollbacks"class="title"style="clear: both">Rollbacks </h2></div></div></div><p>While the <codeclass="literal">home-manager</code> tool does not explicitly support rollbacks at
the moment it is relatively easy to perform one manually. The steps to
do so are</p><divclass="orderedlist"><olclass="orderedlist "type="1"><liclass="listitem"><p>Run <codeclass="literal">home-manager generations</code> to determine which generation you
wish to rollback to:</p><pre><codeclass="programlisting shell">$ home-manager generations
2018-01-04 11:56 : id 765 -> /nix/store/kahm1rxk77mnvd2l8pfvd4jkkffk5ijk-home-manager-generation
2018-01-03 10:29 : id 764 -> /nix/store/2wsmsliqr5yynqkdyjzb1y57pr5q2lsj-home-manager-generation
2018-01-01 12:21 : id 763 -> /nix/store/mv960kl9chn2lal5q8lnqdp1ygxngcd1-home-manager-generation
2017-12-29 21:03 : id 762 -> /nix/store/6c0k1r03fxckql4vgqcn9ccb616ynb94-home-manager-generation
2017-12-25 18:51 : id 761 -> /nix/store/czc5y6vi1rvnkfv83cs3rn84jarcgsgh-home-manager-generation
…
</code></pre></li><liclass="listitem"><p>Copy the Nix store path of the generation you chose, e.g.,</p><pre><codeclass="programlisting">/nix/store/mv960kl9chn2lal5q8lnqdp1ygxngcd1-home-manager-generation
</code></pre><p>for generation 763.</p></li><liclass="listitem"><p>Run the <codeclass="literal">activate</code> script inside the copied store path:</p><pre><codeclass="programlisting shell">$ /nix/store/mv960kl9chn2lal5q8lnqdp1ygxngcd1-home-manager-generation/activate
</div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-usage-dotfiles"class="title"style="clear: both">Keeping your ~ safe from harm </h2></div></div></div><p>To configure programs and services Home Manager must write various
</div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-usage-graphical"class="title"style="clear: both">Graphical services </h2></div></div></div><p>Home Manager includes a number of services intended to run in a
</div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-usage-gpu-non-nixos"class="title"style="clear: both">GPU on non-NixOS systems </h2></div></div></div><p>To access the GPU, programs need access to OpenGL and Vulkan libraries. While
this works transparently on NixOS, it does not on other Linux systems. A
solution is provided by <aclass="link"href="https://github.com/nix-community/nixGL"target="_top">NixGL</a>, which
can be integrated into Home Manager.</p><p>To enable the integration, import NixGL into your home configuration, either as
a channel, or as a flake input passed via <codeclass="literal">extraSpecialArgs</code>. Then, set the
<codeclass="literal">nixGL.packages</code> option to the package set provided by NixGL.</p><p>Once integration is enabled, it can be used in two ways: as Nix functions for
wrapping programs installed via Home Manager, and as shell commands for running
programs installed by other means (such as <codeclass="literal">nix shell</code>). In either case, there
are several wrappers available. They can be broadly categorized</p><divclass="itemizedlist"><ulclass="itemizedlist compact"style="list-style-type: disc;"><liclass="listitem"><p>by vendor: as Mesa (for Free drivers of all vendors) and Nvidia (for
Nvidia-specific proprietary drivers).</p></li><liclass="listitem"><p>by GPU selection: as primary and secondary (offloading).</p></li></ul></div><p>For example, the <codeclass="literal">mesa</code> wrapper provides support for running programs on the
primary GPU for Intel, AMD and Nouveau drivers, while the <codeclass="literal">mesaPrime</code> wrapper
does the same for the secondary GPU.</p><p><spanclass="strong"><strong>Note:</strong></span> when using Nvidia wrappers together with flakes, your home
configuration will not be pure and needs to be built using <codeclass="literal">home-manager switch --impure</code>. Otherwise, the build will fail, complaining about missing attribute
<codeclass="literal">currentTime</code>.</p><p>Wrapper functions are available under <codeclass="literal">config.lib.nixGL.wrappers</code>. However, it
can be more convenient to use the <codeclass="literal">config.lib.nixGL.wrap</code> alias, which can be
configured to use any of the wrappers. It is intended to provide a customization
point when the same home configuration is used across several machines with
different hardware. There is also the <codeclass="literal">config.lib.nixGL.wrapOffload</code> alias for
two-GPU systems.</p><p>Another convenience is that all wrapper functions are always available. However,
when <codeclass="literal">nixGL.packages</code> option is unset, they are no-ops. This allows them to be
used even when the home configuration is used on NixOS machines. The exception
is the <codeclass="literal">prime-offload</code> script which ignores <codeclass="literal">nixGL.packages</code> and is installed
into the environment whenever <codeclass="literal">nixGL.prime.installScript</code> is set. This script,
which can be used to start a program on a secondary GPU, does not depend on
NixGL and is useful on NixOS systems as well.</p><p>Below is an abbreviated example for an Optimus laptop that makes use of both
Mesa and Nvidia wrappers, where the latter is used in dGPU offloading mode. It
demonstrates how to wrap <codeclass="literal">mpv</code> to run on the integrated Intel GPU, wrap FreeCAD
to run on the Nvidia dGPU, and how to install the wrapper scripts. It also wraps
Xonotic to run on the dGPU, but uses the wrapper function directly for
</div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-updating"class="title"style="clear: both">Updating </h2></div></div></div><p>If you have installed Home Manager using the Nix channel method then
</div><divclass="part"><divclass="titlepage"><div><div><h1id="ch-nix-flakes"class="title">Nix Flakes </h1></div></div></div><divclass="partintro"><p>Home Manager is compatible with <aclass="link"href="https://wiki.nixos.org/wiki/Flakes"target="_top">Nix
incompatible ways.</p><p>Just like in the standard installation you can use the Home Manager
flake in three ways:</p><divclass="orderedlist"><olclass="orderedlist "type="1"><liclass="listitem"><p>Using the standalone <codeclass="literal">home-manager</code> tool. For platforms other than
NixOS and Darwin, this is the only available choice. It is also
recommended for people on NixOS or Darwin that want to manage their
home directory independently of the system as a whole. See
<aclass="link"href="index.xhtml#sec-flakes-standalone"title="Standalone setup">Standalone setup</a> for instructions on how
to perform this installation.</p></li><liclass="listitem"><p>As a module within a NixOS system configuration. This allows the
user profiles to be built together with the system when running
<codeclass="literal">nixos-rebuild</code>. See <aclass="link"href="index.xhtml#sec-flakes-nixos-module"title="NixOS module">NixOS module</a> for a
description of this setup.</p></li><liclass="listitem"><p>This allows the user profiles to be built together with the system
when running <codeclass="literal">darwin-rebuild</code>. See <aclass="link"href="index.xhtml#sec-flakes-nix-darwin-module"title="nix-darwin module">nix-darwin
setup.</p></li></ol></div><divclass="toc"><p><strong>Table of Contents</strong></p><dlclass="toc"><dt><spanclass="section"><ahref="index.xhtml#sec-flakes-prerequisites">Prerequisites</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-flakes-standalone">Standalone setup</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-flakes-nixos-module">NixOS module</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-flakes-nix-darwin-module">nix-darwin module</a></span></dt></dl></div></div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-flakes-prerequisites"class="title"style="clear: both">Prerequisites </h2></div></div></div><divclass="itemizedlist"><ulclass="itemizedlist "style="list-style-type: disc;"><liclass="listitem"><p>Install Nix 2.4 or later, or have it in <codeclass="literal">nix-shell</code>.</p></li><liclass="listitem"><p>Enable experimental features <codeclass="literal">nix-command</code> and <codeclass="literal">flakes</code>.</p><divclass="itemizedlist"><ulclass="itemizedlist "style="list-style-type: circle;"><liclass="listitem"><p>When using NixOS, add the following to your <codeclass="literal">configuration.nix</code>
and rebuild your system.</p><pre><codeclass="programlisting nix">nix = {
package = pkgs.nixFlakes;
extraOptions = ''
experimental-features = nix-command flakes
'';
};
</code></pre></li><liclass="listitem"><p>If you are not using NixOS, add the following to <codeclass="literal">nix.conf</code>
(located at <codeclass="literal">~/.config/nix/</code> or <codeclass="literal">/etc/nix/nix.conf</code>).</p><pre><codeclass="programlisting bash">experimental-features = nix-command flakes
</code></pre><p>You may need to restart the Nix daemon with, for example,
<codeclass="literal">sudo systemctl restart nix-daemon.service</code>.</p></li><liclass="listitem"><p>Alternatively, you can enable flakes on a per-command basis with
the following additional flags to <codeclass="literal">nix</code> and <codeclass="literal">home-manager</code>:</p><pre><codeclass="programlisting shell">$ nix --extra-experimental-features "nix-command flakes"<sub-commands>
</code></pre></li></ul></div></li><liclass="listitem"><p>Prepare your Home Manager configuration (<codeclass="literal">home.nix</code>).</p><p>Unlike the channel-based setup, <codeclass="literal">home.nix</code> will be evaluated when
the flake is built, so it must be present before bootstrap of Home
Manager from the flake. See <aclass="link"href="index.xhtml#sec-usage-configuration"title="Configuration Example">Configuration Example</a> for
introduction about writing a Home Manager configuration.</p></li></ul></div>
</div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-flakes-standalone"class="title"style="clear: both">Standalone setup </h2></div></div></div><p>To prepare an initial Home Manager configuration for your logged in
user, you can run the Home Manager <codeclass="literal">init</code> command directly from its
flake.</p><p>For example, if you are using the unstable version of Nixpkgs or NixOS,
then to generate and activate a basic configuration run the command</p><pre><codeclass="programlisting shell">$ nix run home-manager/master -- init --switch
</code></pre><p>This will generate a <codeclass="literal">flake.nix</code> and a <codeclass="literal">home.nix</code> file in
<codeclass="literal">~/.config/home-manager</code>, creating the directory if it does not exist.</p><p>If you omit the <codeclass="literal">--switch</code> option then the activation will not happen.
This is useful if you want to inspect and edit the configuration before
activating it.</p><pre><codeclass="programlisting shell">$ nix run home-manager/$branch -- init
</code></pre><p>Where <codeclass="literal">$branch</code> is one of <codeclass="literal">master</code> or <codeclass="literal">release-24.11</code>.</p><p>After the initial activation has completed successfully then building
and activating your flake-based configuration is as simple as</p><pre><codeclass="programlisting shell">$ home-manager switch
</code></pre><p>It is possible to override the default configuration directory, if you
want. For example,</p><pre><codeclass="programlisting shell">$ nix run home-manager/$branch -- init --switch ~/hmconf
$ # And after the initial activation.
$ home-manager switch --flake ~/hmconf
</code></pre><divclass="note"><h3class="title">Note</h3><p>The flake inputs are not automatically updated by Home Manager. You need
to use the standard <codeclass="literal">nix flake update</code> command for that.</p><p>If you only want to update a single flake input, then the command
<codeclass="literal">nix flake lock --update-input <input></code> can be used.</p><p>You can also pass flake-related options such as <codeclass="literal">--recreate-lock-file</code>
or <codeclass="literal">--update-input <input></code> to <codeclass="literal">home-manager</code> when building or
switching, and these options will be forwarded to <codeclass="literal">nix build</code>. See the
</div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-flakes-nixos-module"class="title"style="clear: both">NixOS module </h2></div></div></div><p>To use Home Manager as a NixOS module, a bare-minimum <codeclass="literal">flake.nix</code> would
# Optionally, use home-manager.extraSpecialArgs to pass
# arguments to home.nix
}
];
};
};
};
}
</code></pre><p>The Home Manager configuration is then part of the NixOS configuration
and is automatically rebuilt with the system when using the appropriate
command for the system, such as
<codeclass="literal">nixos-rebuild switch --flake <flake-uri></code>.</p><p>You can use the above <codeclass="literal">flake.nix</code> as a template in <codeclass="literal">/etc/nixos</code> by</p><pre><codeclass="programlisting shell">$ nix flake new /etc/nixos -t github:nix-community/home-manager#nixos
</div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-flakes-nix-darwin-module"class="title"style="clear: both">nix-darwin module </h2></div></div></div><p>The flake-based setup of the Home Manager nix-darwin module is similar
# Optionally, use home-manager.extraSpecialArgs to pass
# arguments to home.nix
}
];
};
};
};
}
</code></pre><p>and it is also rebuilt with the nix-darwin generations. The rebuild
command here may be <codeclass="literal">darwin-rebuild switch --flake <flake-uri></code>.</p><p>You can use the above <codeclass="literal">flake.nix</code> as a template in <codeclass="literal">~/.config/darwin</code> by</p><pre><codeclass="programlisting shell">$ nix flake new ~/.config/darwin -t github:nix-community/home-manager#nix-darwin
</div><divclass="part"><divclass="titlepage"><div><div><h1id="ch-writing-modules"class="title">Writing Home Manager Modules </h1></div></div></div><divclass="partintro"><p>The module system in Home Manager is based entirely on the NixOS module
chapter of the NixOS manual.</p><divclass="toc"><p><strong>Table of Contents</strong></p><dlclass="toc"><dt><spanclass="section"><ahref="index.xhtml#sec-option-types">Option Types</a></span></dt></dl></div></div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-option-types"class="title"style="clear: both">Option Types </h2></div></div></div><p>Overall the basic option types are the same in Home Manager as NixOS. A
<aclass="link"href="options.xhtml#opt-programs.ssh.matchBlocks">programs.ssh.matchBlocks</a> and <aclass="link"href="options.xhtml#opt-dconf.settings">dconf.settings</a>.</p><divclass="variablelist"><dlclass="variablelist"><dt><spanclass="term"><spanid="sec-option-types-dag"></span><codeclass="literal">hm.types.dagOf</code></span></dt><dd><p>Options of this type have attribute sets as values where each member
is a node in a <aclass="link"href="https://en.wikipedia.org/w/index.php?title=Directed_acyclic_graph&oldid=939656095"target="_top">directed acyclic
graph</a>
(DAG). This allows the attribute set entries to express dependency
relations among themselves. This can, for example, be used to
control the order of match blocks in a OpenSSH client configuration
type <codeclass="literal">hm.types.dagOf types.int</code>.</p><divclass="variablelist"><dlclass="variablelist"><dt><spanclass="term"><spanid="sec-option-types-dag-entryAnywhere"></span><codeclass="literal">hm.dag.entryAnywhere (value: T) : DagEntry<T></code></span></dt><dd><p>Indicates that <codeclass="literal">value</code> can be placed anywhere within the DAG.
</code></pre><p>are equivalent.</p></dd><dt><spanclass="term"><spanid="sec-option-types-dag-entryAfter"></span><codeclass="literal">hm.dag.entryAfter (afters: list string) (value: T) : DagEntry<T></code></span></dt><dd><p>Indicates that <codeclass="literal">value</code> must be placed <spanclass="emphasis"><em>after</em></span> each of the
</code></pre><p>would place <codeclass="literal">b</code> after <codeclass="literal">a</code> in the graph.</p></dd><dt><spanclass="term"><spanid="sec-option-types-dag-entryBefore"></span><codeclass="literal">hm.dag.entryBefore (befores: list string) (value: T) : DagEntry<T></code></span></dt><dd><p>Indicates that <codeclass="literal">value</code> must be placed <spanclass="emphasis"><em>before</em></span> each of the
</code></pre><p>would place <codeclass="literal">b</code> before <codeclass="literal">a</code> in the graph.</p></dd><dt><spanclass="term"><spanid="sec-option-types-dag-entryBetween"></span><codeclass="literal">hm.dag.entryBetween (befores: list string) (afters: list string) (value: T) : DagEntry<T></code></span></dt><dd><p>Indicates that <codeclass="literal">value</code> must be placed <spanclass="emphasis"><em>before</em></span> the attribute
names in the first list and <spanclass="emphasis"><em>after</em></span> the attribute names in the
second list. For example</p><pre><codeclass="programlisting nix">foo.bar = {
a = 0;
c = hm.dag.entryBetween [ "b" ] [ "a" ] 2;
b = 1;
}
</code></pre><p>would place <codeclass="literal">c</code> before <codeclass="literal">b</code> and after <codeclass="literal">a</code> in the graph.</p></dd></dl></div><p>There are also a set of functions that generate a DAG from a list.
These are convenient when you just want to have a linear list of DAG
entries, without having to manually enter the relationship between
each entry. Each of these functions take a <codeclass="literal">tag</code> as argument and the
DAG entries will be named <codeclass="literal">${tag}-${index}</code>.</p><divclass="variablelist"><dlclass="variablelist"><dt><spanclass="term"><spanid="sec-option-types-dag-entriesAnywhere"></span><codeclass="literal">hm.dag.entriesAnywhere (tag: string) (values: [T]) : Dag<T></code></span></dt><dd><p>Creates a DAG with the given values with each entry labeled
</code></pre></dd><dt><spanclass="term"><spanid="sec-option-types-dag-entriesAfter"></span><codeclass="literal">hm.dag.entriesAfter (tag: string) (afters: list string) (values: [T]) : Dag<T></code></span></dt><dd><p>Creates a DAG with the given values with each entry labeled
using the given tag. The list of values are placed are placed
<spanclass="emphasis"><em>after</em></span> each of the attribute names in <codeclass="literal">afters</code>. For example</p><pre><codeclass="programlisting nix">foo.bar =
</code></pre></dd><dt><spanclass="term"><spanid="sec-option-types-dag-entriesBefore"></span><codeclass="literal">hm.dag.entriesBefore (tag: string) (befores: list string) (values: [T]) : Dag<T></code></span></dt><dd><p>Creates a DAG with the given values with each entry labeled
</code></pre></dd><dt><spanclass="term"><spanid="sec-option-types-dag-entriesBetween"></span><codeclass="literal">hm.dag.entriesBetween (tag: string) (befores: list string) (afters: list string) (values: [T]) : Dag<T></code></span></dt><dd><p>Creates a DAG with the given values with each entry labeled
</code></pre></dd></dl></div></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant"></span><codeclass="literal">hm.types.gvariant</code></span></dt><dd><p>This type is useful for options representing
of type <codeclass="literal">hm.types.gvariant</code>.</p><divclass="variablelist"><dlclass="variablelist"><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkBoolean"></span><codeclass="literal">hm.gvariant.mkBoolean (v: bool)</code></span></dt><dd><p>Takes a Nix value <codeclass="literal">v</code> to a GVariant <codeclass="literal">boolean</code> value (GVariant
</code></pre></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkString"></span><codeclass="literal">hm.gvariant.mkString (v: string)</code></span></dt><dd><p>Takes a Nix value <codeclass="literal">v</code> to a GVariant <codeclass="literal">string</code> value (GVariant
</code></pre></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkObjectpath"></span><codeclass="literal">hm.gvariant.mkObjectpath (v: string)</code></span></dt><dd><p>Takes a Nix value <codeclass="literal">v</code> to a GVariant <codeclass="literal">objectpath</code> value (GVariant
format string <codeclass="literal">o</code>).</p></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkUchar"></span><codeclass="literal">hm.gvariant.mkUchar (v: string)</code></span></dt><dd><p>Takes a Nix value <codeclass="literal">v</code> to a GVariant <codeclass="literal">uchar</code> value (GVariant
format string <codeclass="literal">y</code>).</p></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkInt16"></span><codeclass="literal">hm.gvariant.mkInt16 (v: int)</code></span></dt><dd><p>Takes a Nix value <codeclass="literal">v</code> to a GVariant <codeclass="literal">int16</code> value (GVariant
format string <codeclass="literal">n</code>).</p></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkUint16"></span><codeclass="literal">hm.gvariant.mkUint16 (v: int)</code></span></dt><dd><p>Takes a Nix value <codeclass="literal">v</code> to a GVariant <codeclass="literal">uint16</code> value (GVariant
format string <codeclass="literal">q</code>).</p></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkInt32"></span><codeclass="literal">hm.gvariant.mkInt32 (v: int)</code></span></dt><dd><p>Takes a Nix value <codeclass="literal">v</code> to a GVariant <codeclass="literal">int32</code> value (GVariant
</code></pre></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkUint32"></span><codeclass="literal">hm.gvariant.mkUint32 (v: int)</code></span></dt><dd><p>Takes a Nix value <codeclass="literal">v</code> to a GVariant <codeclass="literal">uint32</code> value (GVariant
format string <codeclass="literal">u</code>).</p></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkInt64"></span><codeclass="literal">hm.gvariant.mkInt64 (v: int)</code></span></dt><dd><p>Takes a Nix value <codeclass="literal">v</code> to a GVariant <codeclass="literal">int64</code> value (GVariant
format string <codeclass="literal">x</code>).</p></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkUint64"></span><codeclass="literal">hm.gvariant.mkUint64 (v: int)</code></span></dt><dd><p>Takes a Nix value <codeclass="literal">v</code> to a GVariant <codeclass="literal">uint64</code> value (GVariant
format string <codeclass="literal">t</code>).</p></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkDouble"></span><codeclass="literal">hm.gvariant.mkDouble (v: double)</code></span></dt><dd><p>Takes a Nix value <codeclass="literal">v</code> to a GVariant <codeclass="literal">double</code> value (GVariant
</code></pre></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkArray"></span><codeclass="literal">hm.gvariant.mkArray type elements</code></span></dt><dd><p>Builds a GVariant array containing the given list of elements,
where each element is a GVariant value of the given type
(GVariant format string <codeclass="literal">a${type}</code>). The <codeclass="literal">type</code> value can be
constructed using</p><divclass="itemizedlist"><ulclass="itemizedlist "style="list-style-type: disc;"><liclass="listitem"><p><codeclass="literal">hm.gvariant.type.string</code> (GVariant format string <codeclass="literal">s</code>)</p></li><liclass="listitem"><p><codeclass="literal">hm.gvariant.type.boolean</code> (GVariant format string <codeclass="literal">b</code>)</p></li><liclass="listitem"><p><codeclass="literal">hm.gvariant.type.uchar</code> (GVariant format string <codeclass="literal">y</code>)</p></li><liclass="listitem"><p><codeclass="literal">hm.gvariant.type.int16</code> (GVariant format string <codeclass="literal">n</code>)</p></li><liclass="listitem"><p><codeclass="literal">hm.gvariant.type.uint16</code> (GVariant format string <codeclass="literal">q</code>)</p></li><liclass="listitem"><p><codeclass="literal">hm.gvariant.type.int32</code> (GVariant format string <codeclass="literal">i</code>)</p></li><liclass="listitem"><p><codeclass="literal">hm.gvariant.type.uint32</code> (GVariant format string <codeclass="literal">u</code>)</p></li><liclass="listitem"><p><codeclass="literal">hm.gvariant.type.int64</code> (GVariant format string <codeclass="literal">x</code>)</p></li><liclass="listitem"><p><codeclass="literal">hm.gvariant.type.uint64</code> (GVariant format string <codeclass="literal">t</code>)</p></li><liclass="listitem"><p><codeclass="literal">hm.gvariant.type.double</code> (GVariant format string <codeclass="literal">d</code>)</p></li><liclass="listitem"><p><codeclass="literal">hm.gvariant.type.variant</code> (GVariant format string <codeclass="literal">v</code>)</p></li><liclass="listitem"><p><codeclass="literal">hm.gvariant.type.arrayOf type</code> (GVariant format string
<codeclass="literal">a${type}</code>)</p></li><liclass="listitem"><p><codeclass="literal">hm.gvariant.type.maybeOf type</code> (GVariant format string
<codeclass="literal">m${type}</code>)</p></li><liclass="listitem"><p><codeclass="literal">hm.gvariant.type.tupleOf types</code> (GVariant format string
(GVariant format string <codeclass="literal">{${keyType}${valueType}}</code>)</p></li></ul></div><p>where <codeclass="literal">type</code> and <codeclass="literal">types</code> are themselves a type and list of
types, respectively.</p></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkEmptyArray"></span><codeclass="literal">hm.gvariant.mkEmptyArray type</code></span></dt><dd><p>An alias of
<aclass="link"href="index.xhtml#sec-option-types-gvariant-mkArray"><codeclass="literal">hm.gvariant.mkArray type []</code></a>.</p></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkNothing"></span><codeclass="literal">hm.gvariant.mkNothing type</code></span></dt><dd><p>Builds a GVariant maybe value (GVariant format string
<aclass="link"href="index.xhtml#sec-option-types-gvariant-mkArray"><codeclass="literal">mkArray</code></a> function above.</p></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkJust"></span><codeclass="literal">hm.gvariant.mkJust element</code></span></dt><dd><p>Builds a GVariant maybe value (GVariant format string
<codeclass="literal">m${element.type}</code>) containing the given GVariant element.</p></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkTuple"></span><codeclass="literal">hm.gvariant.mkTuple elements</code></span></dt><dd><p>Builds a GVariant tuple containing the given list of elements,
where each element is a GVariant value.</p></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkVariant"></span><codeclass="literal">hm.gvariant.mkVariant element</code></span></dt><dd><p>Builds a GVariant variant (GVariant format string <codeclass="literal">v</code>) which
contains the value of a GVariant element.</p></dd><dt><spanclass="term"><spanid="sec-option-types-gvariant-mkDictionaryEntry"></span><codeclass="literal">hm.gvariant.mkDictionaryEntry [key value]</code></span></dt><dd><p>Builds a GVariant dictionary entry containing the given list of
</div><divclass="part"><divclass="titlepage"><div><div><h1id="ch-contributing"class="title">Contributing </h1></div></div></div><divclass="partintro"><p>Contributions to Home Manager are very welcome. To make the process as
configuration.</p><divclass="toc"><p><strong>Table of Contents</strong></p><dlclass="toc"><dt><spanclass="section"><ahref="index.xhtml#sec-contrib-getting-started">Getting started</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-guidelines">Guidelines</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-news">News</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-tests">Tests</a></span></dt></dl></div></div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-contrib-getting-started"class="title"style="clear: both">Getting started </h2></div></div></div><p>If you have not previously forked Home Manager then you need to do that
first. Have a look at GitHub’s <aclass="link"href="https://help.github.com/articles/fork-a-repo/"target="_top">Fork a
repo</a> for instructions on
how to do this.</p><p>Once you have a fork of Home Manager you should create a branch starting
at the most recent <codeclass="literal">master</code> branch. Give your branch a reasonably
descriptive name. Commit your changes to this branch and when you are
happy with the result and it fulfills <aclass="link"href="index.xhtml#sec-guidelines"title="Guidelines">Guidelines</a> then
push the branch to GitHub and <aclass="link"href="https://help.github.com/articles/creating-a-pull-request/"target="_top">create a pull
request</a>.</p><p>Assuming your clone is at <codeclass="literal">$HOME/devel/home-manager</code> then you can make
the <codeclass="literal">home-manager</code> command use it by either</p><divclass="orderedlist"><olclass="orderedlist "type="1"><liclass="listitem"><p>overriding the default path by using the <codeclass="literal">-I</code> command line option:</p><pre><codeclass="programlisting shell">$ home-manager -I home-manager=$HOME/devel/home-manager
</code></pre><p>or, if using <aclass="link"href="index.xhtml#sec-flakes-standalone"title="Standalone setup">flakes</a>:</p><pre><codeclass="programlisting shell">$ home-manager --override-input home-manager ~/devel/home-manager
</code></pre><p>or</p></li><liclass="listitem"><p>changing the default path by ensuring your configuration includes</p><pre><codeclass="programlisting nix">programs.home-manager.enable = true;
</div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-guidelines"class="title"style="clear: both">Guidelines </h2></div></div></div><divclass="toc"><dlclass="toc"><dt><spanclass="section"><ahref="index.xhtml#sec-guidelines-back-compat">Maintain backward compatibility</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-guidelines-forward-compat">Keep forward compatibility in mind</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-guidelines-valuable-options">Add only valuable options</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-guidelines-add-tests">Add relevant tests</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-guidelines-module-maintainer">Add relevant documentation</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#_add_yourself_as_a_module_maintainer">Add yourself as a module maintainer</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-guidelines-code-style">Format your code</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-guidelines-commit-message-style">Format your commit messages</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-guidelines-news-style">Format your news entries</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-guidelines-conditional-modules">Use conditional modules and news</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-guidelines-licensing">Mind the license</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-commit-style">Commits</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#ex-commit-message">Example commit</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#sec-code-style">Code Style</a></span></dt></dl></div><p>If your contribution satisfy the following rules then there is a good
channel, ideally before you start developing.</p><divclass="section"><divclass="titlepage"><div><div><h3id="sec-guidelines-back-compat"class="title">Maintain backward compatibility </h3></div></div></div><p>Your contribution should not cause another user’s existing configuration
or similar.</p><p>Remember that Home Manager is used in many different environments and
you should consider how your change may effect others. For example,</p><divclass="itemizedlist"><ulclass="itemizedlist "style="list-style-type: disc;"><liclass="listitem"><p>Does your change work for people that do not use NixOS? Consider
other GNU/Linux distributions and macOS.</p></li><liclass="listitem"><p>Does your change work for people whose configuration is built on one
system and deployed on another system?</p></li></ul></div>
</div><divclass="section"><divclass="titlepage"><div><div><h3id="sec-guidelines-forward-compat"class="title">Keep forward compatibility in mind </h3></div></div></div><p>The master branch of Home Manager tracks the unstable channel of
</div><divclass="section"><divclass="titlepage"><div><div><h3id="sec-guidelines-valuable-options"class="title">Add only valuable options </h3></div></div></div><p>When creating a new module it is tempting to include every option
supported by the software. This is <spanclass="emphasis"><em>strongly</em></span> discouraged. Providing
many options increases maintenance burden and risk of breakage
considerably. This is why only the most <aclass="link"href="https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md#valuable-options"target="_top">important software
options</a>
should be modeled explicitly. Less important options should be
expressible through an <codeclass="literal">extraConfig</code> escape hatch.</p><p>A good rule of thumb for the first implementation of a module is to only
add explicit options for those settings that absolutely must be set for
the software to function correctly. It follows that a module for
software that provides sensible default values for all settings would
require no explicit options at all.</p><p>If the software uses a structured configuration format like a JSON,
YAML, INI, TOML, or even a plain list of key/value pairs then consider
using a <codeclass="literal">settings</code> option as described in <aclass="link"href="https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md"target="_top">Nix RFC
</div><divclass="section"><divclass="titlepage"><div><div><h3id="sec-guidelines-add-tests"class="title">Add relevant tests </h3></div></div></div><p>If at all possible, make sure to add new tests and expand existing tests
</div><divclass="section"><divclass="titlepage"><div><div><h3id="sec-guidelines-module-maintainer"class="title">Add relevant documentation </h3></div></div></div><p>Many code changes require changing the documentation as well. The
</div><divclass="section"><divclass="titlepage"><div><div><h3id="_add_yourself_as_a_module_maintainer"class="title">Add yourself as a module maintainer </h3></div></div></div><p>Every new module <spanclass="emphasis"><em>must</em></span> include a named maintainer using the
</div><divclass="section"><divclass="titlepage"><div><div><h3id="sec-guidelines-code-style"class="title">Format your code </h3></div></div></div><p>Make sure your code is formatted as described in <aclass="link"href="index.xhtml#sec-code-style"title="Code Style">Code
</div><divclass="section"><divclass="titlepage"><div><div><h3id="sec-guidelines-commit-message-style"class="title">Format your commit messages </h3></div></div></div><p>Similar to <aclass="link"href="index.xhtml#sec-guidelines-code-style"title="Format your code">Format your code</a> we encourage a
</div><divclass="section"><divclass="titlepage"><div><div><h3id="sec-guidelines-news-style"class="title">Format your news entries </h3></div></div></div><p>If your contribution includes a change that should be communicated to
users of Home Manager then you can add a news entry. The entry must be
formatted as described in <aclass="link"href="index.xhtml#sec-news"title="News">News</a>.</p><p>When new modules are added a news entry should be included but you do
not need to create this entry manually. The merging maintainer will
create the entry for you. This is to reduce the risk of merge conflicts.</p>
</div><divclass="section"><divclass="titlepage"><div><div><h3id="sec-guidelines-conditional-modules"class="title">Use conditional modules and news </h3></div></div></div><p>Home Manager includes a number of modules that are only usable on some
of the supported platforms. The most common example of platform specific
modules are those that define systemd user services, which only works on
Linux systems.</p><p>If you add a module that is platform specific then make sure to include
a condition in the <codeclass="literal">loadModule</code> function call. This will make the module
accessible only on systems where the condition evaluates to <codeclass="literal">true</code>.</p><p>Similarly, if you are adding a news entry then it should be shown only
to users that may find it relevant, see <aclass="link"href="index.xhtml#sec-news"title="News">News</a> for a
</div><divclass="section"><divclass="titlepage"><div><div><h3id="sec-guidelines-licensing"class="title">Mind the license </h3></div></div></div><p>The Home Manager project is covered by the MIT license and we can only
</div><divclass="section"><divclass="titlepage"><div><div><h3id="sec-commit-style"class="title">Commits </h3></div></div></div><p>The commits in your pull request should be reasonably self-contained,
that is, each commit should make sense in isolation. In particular, you
will be asked to amend any commit that introduces syntax errors or
similar problems even if they are fixed in a later commit.</p><p>The commit messages should follow the <aclass="link"href="https://chris.beams.io/posts/git-commit/#seven-rules"target="_top">seven
rules</a>, except for
"Capitalize the subject line". We also ask you to include the affected
code component or module in the first line. That is, a commit message
should follow the template</p><pre><codeclass="programlisting">{component}: {description}
{long description}
</code></pre><p>where <codeclass="literal">{component}</code> refers to the code component (or module) your change
affects, <codeclass="literal">{description}</code> is a very brief description of your change, and
<codeclass="literal">{long description}</code> is an optional clarifying description. As a rare
exception, if there is no clear component, or your change affects many
components, then the <codeclass="literal">{component}</code> part is optional. See
<aclass="link"href="index.xhtml#ex-commit-message"title="Example commit">example_title</a> for a commit message that fulfills
contains the commit message</p><pre><codeclass="programlisting">
starship: allow running in Emacs if vterm is used
The vterm buffer is backed by libvterm and can handle Starship prompts
without issues.
</code></pre><p>which ticks all the boxes necessary to be accepted in Home Manager.</p><p>Finally, when adding a new module, say <codeclass="literal">programs/foo.nix</code>, we use the
fixed commit format <codeclass="literal">foo: add module</code>. You can, of course, still include
</div><divclass="section"><divclass="titlepage"><div><div><h3id="sec-code-style"class="title">Code Style </h3></div></div></div><p>The code in Home Manager is formatted by the
</div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-news"class="title"style="clear: both">News </h2></div></div></div><p>Home Manager includes a system for presenting news to the user. When
but you should follow some basic guidelines:</p><divclass="itemizedlist"><ulclass="itemizedlist "style="list-style-type: disc;"><liclass="listitem"><p>The entry timestamp should be in ISO-8601 format having "+00:00"
as time zone. For example, "2017-09-13T17:10:14+00:00". A suitable
timestamp can be produced by the command</p><pre><codeclass="programlisting shell">$ date --iso-8601=second --universal
</code></pre></li><liclass="listitem"><p>The entry condition should be as specific as possible. For example,
if you are changing or deprecating a specific option then you could
restrict the news to those users who actually use this option.</p></li><liclass="listitem"><p>Wrap the news message so that it will fit in the typical terminal,
that is, at most 80 characters wide. Ideally a bit less.</p></li><liclass="listitem"><p>Unlike commit messages, news will be read without any connection to
the Home Manager source code. It is therefore important to make the
message understandable in isolation and to those who do not have
knowledge of the Home Manager internals. To this end it should be
written in more descriptive, prose like way.</p></li><liclass="listitem"><p>If you refer to an option then write its full attribute path. That
is, instead of writing</p><pre><codeclass="programlisting">The option 'foo' has been deprecated, please use 'bar' instead.
</code></pre><p>it should read</p><pre><codeclass="programlisting">The option 'services.myservice.foo' has been deprecated, please
use 'services.myservice.bar' instead.
</code></pre></li><liclass="listitem"><p>A new module, say <codeclass="literal">foo.nix</code>, should always include a news entry that
has a message along the lines of</p><pre><codeclass="programlisting">A new module is available: 'services.foo'.
</code></pre><p>If the module is platform specific, e.g., a service module using
systemd, then a condition like</p><pre><codeclass="programlisting nix">condition = hostPlatform.isLinux;
</code></pre><p>should be added. If you contribute a module then you don’t need to
add this entry, the merger will create an entry for you.</p></li></ul></div>
</div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-tests"class="title"style="clear: both">Tests </h2></div></div></div><p>Home Manager includes a basic test suite and it is highly recommended to
include at least one test when adding a module. Tests are typically in
the form of "golden tests" where, for example, a generated
configuration file is compared to a known correct file.</p><p>It is relatively easy to create tests by modeling the existing tests,
found in the <codeclass="literal">tests</code> project directory. For a full reference to the
functions available in test scripts, you can look at NMT’s
<aclass="link"href="https://git.sr.ht/~rycee/nmt/tree/master/item/bash-lib"target="_top">bash-lib</a>.</p><p>The full Home Manager test suite can be run by executing</p><pre><codeclass="programlisting shell">$ nix-shell --pure tests -A run.all
</code></pre><p>in the project root. List all test cases through</p><pre><codeclass="programlisting shell">$ nix-shell --pure tests -A list
</code></pre><p>and run an individual test, for example <codeclass="literal">alacritty-empty-settings</code>,
through</p><pre><codeclass="programlisting shell">$ nix-shell --pure tests -A run.alacritty-empty-settings
</code></pre><p>However, those invocations will impurely source the system’s nixpkgs,
and may cause failures. To run against the nixpkgs from the flake.lock,
use instead e.g.</p><pre><codeclass="programlisting shell">$ nix develop --ignore-environment .#all
</div><divclass="part"><divclass="titlepage"><div><div><h1id="ch-3rd-party"class="title">Third-Party Tools and Extensions </h1></div></div></div><divclass="partintro"><p>Here is a collection of tools and extensions that relate to Home
are encouraged to create a PR that expands this chapter.</p><divclass="toc"><p><strong>Table of Contents</strong></p><dlclass="toc"><dt><spanclass="section"><ahref="index.xhtml#sec-3rd-party-module-collections">Module Collections</a></span></dt></dl></div></div><divclass="section"><divclass="titlepage"><div><div><h2id="sec-3rd-party-module-collections"class="title"style="clear: both">Module Collections </h2></div></div></div><divclass="itemizedlist"><ulclass="itemizedlist "style="list-style-type: disc;"><liclass="listitem"><p><aclass="link"href="https://github.com/schuelermine/xhmm"target="_top">xhmm — extra Home Manager
modules</a></p><p>A collection of modules maintained by Anselm Schüler.</p></li><liclass="listitem"><p><aclass="link"href="https://github.com/danth/stylix/"target="_top">Stylix — System-wide colorscheming and
typography</a></p><p>Configure your applications to get coherent color scheme and font.</p></li></ul></div>
</div><divclass="part"><divclass="titlepage"><div><div><h1id="ch-faq"class="title">Frequently Asked Questions (FAQ) </h1></div></div></div><divclass="partintro"><divclass="toc"><p><strong>Table of Contents</strong></p><dlclass="toc"><dt><spanclass="section"><ahref="index.xhtml#_why_is_there_a_collision_error_when_switching_generation">Why is there a collision error when switching generation?</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#_why_are_the_session_variables_not_set">Why are the session variables not set?</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#_how_to_set_up_a_configuration_for_multiple_users_machines">How to set up a configuration for multiple users/machines?</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#_why_do_i_get_an_error_message_about_literal_ca_desrt_dconf_literal_or_literal_dconf_service_literal">Why do I get an error message about <codeclass="literal">ca.desrt.dconf</code> or <codeclass="literal">dconf.service</code>?</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#_how_do_i_install_packages_from_nixpkgs_unstable">How do I install packages from Nixpkgs unstable?</a></span></dt><dt><spanclass="section"><ahref="index.xhtml#_how_do_i_change_the_package_used_by_a_module">How do I change the package used by a module?</a></span></dt></dl></div></div><divclass="section"><divclass="titlepage"><div><div><h2id="_why_is_there_a_collision_error_when_switching_generation"class="title"style="clear: both">Why is there a collision error when switching generation? </h2></div></div></div><p>Home Manager currently installs packages into the user environment,
building path(s) ‘/nix/store/b5c0asjz9f06l52l9812w6k39ifr49jj-user-environment’
Wide character in die at /nix/store/64jc9gd2rkbgdb4yjx3nrgc91bpjj5ky-buildenv.pl line 79.
collision between ‘/nix/store/fmwa4axzghz11cnln5absh31nbhs9lq1-home-manager-path/bin/hello’ and ‘/nix/store/c2wyl8b9p4afivpcz8jplc9kis8rj36d-hello-2.10/bin/hello’; use ‘nix-env --set-flag priority NUMBER PKGNAME’ to change the priority of one of the conflicting packages
builder for ‘/nix/store/b37x3s7pzxbasfqhaca5dqbf3pjjw0ip-user-environment.drv’ failed with exit code 2
error: build of ‘/nix/store/b37x3s7pzxbasfqhaca5dqbf3pjjw0ip-user-environment.drv’ failed
</code></pre><p>The solution is typically to uninstall the package from the environment
using <codeclass="literal">nix-env --uninstall</code> and reattempt the Home Manager generation
switch.</p><p>You could also opt to unistall <spanclass="emphasis"><em>all</em></span> of the packages from your profile
with <codeclass="literal">nix-env --uninstall '*'</code>.</p>
</div><divclass="section"><divclass="titlepage"><div><div><h2id="_why_are_the_session_variables_not_set"class="title"style="clear: both">Why are the session variables not set? </h2></div></div></div><p>Home Manager is only able to set session variables automatically if it
management you use <aclass="link"href="options.xhtml#opt-programs.bash.enable">programs.bash.enable</a>,
<aclass="link"href="options.xhtml#opt-programs.zsh.enable">programs.zsh.enable</a>, or <aclass="link"href="options.xhtml#opt-programs.fish.enable">programs.fish.enable</a>.</p><p>If you don’t want to let Home Manager manage your shell then you will
<codeclass="literal">~/.nix-profile/etc/profile.d/hm-session-vars.sh</code> file in an appropriate
way. In Bash and Z shell this can be done by adding</p><pre><codeclass="programlisting bash">. "$HOME/.nix-profile/etc/profile.d/hm-session-vars.sh"
</code></pre><p>to your <codeclass="literal">.profile</code> and <codeclass="literal">.zshrc</code> files, respectively. The
<codeclass="literal">hm-session-vars.sh</code> file should work in most Bourne-like shells. For
fish shell, it is possible to source it using <aclass="link"href="https://github.com/oh-my-fish/plugin-foreign-env"target="_top">the foreign-env
</div><divclass="section"><divclass="titlepage"><div><div><h2id="_how_to_set_up_a_configuration_for_multiple_users_machines"class="title"style="clear: both">How to set up a configuration for multiple users/machines? </h2></div></div></div><p>A typical way to prepare a repository of configurations for multiple
logins and machines is to prepare one "top-level" file for each unique
combination.</p><p>For example, if you have two machines, called "kronos" and "rhea" on
which you want to configure your user "jane" then you could create the
files</p><divclass="itemizedlist"><ulclass="itemizedlist "style="list-style-type: disc;"><liclass="listitem"><p><codeclass="literal">kronos-jane.nix</code>,</p></li><liclass="listitem"><p><codeclass="literal">rhea-jane.nix</code>, and</p></li><liclass="listitem"><p><codeclass="literal">common.nix</code></p></li></ul></div><p>in your repository. On the kronos and rhea machines you can then make
<codeclass="literal">~jane/.config/home-manager/home.nix</code> be a symbolic link to the
corresponding file in your configuration repository.</p><p>The <codeclass="literal">kronos-jane.nix</code> and <codeclass="literal">rhea-jane.nix</code> files follow the format</p><pre><codeclass="programlisting nix">{ ... }:
{
imports = [ ./common.nix ];
# Various options that are specific for this machine/user.
}
</code></pre><p>while the <codeclass="literal">common.nix</code> file contains configuration shared across the two
logins. Of course, instead of just a single <codeclass="literal">common.nix</code> file you can
have multiple ones, even one per program or service.</p><p>You can get some inspiration from the <aclass="link"href="https://www.reddit.com/r/NixOS/comments/9bb9h9/post_your_homemanager_homenix_file/"target="_top">Post your home-manager home.nix
</div><divclass="section"><divclass="titlepage"><div><div><h2id="_why_do_i_get_an_error_message_about_literal_ca_desrt_dconf_literal_or_literal_dconf_service_literal"class="title"style="clear: both">Why do I get an error message about <codeclass="literal">ca.desrt.dconf</code> or <codeclass="literal">dconf.service</code>? </h2></div></div></div><p>You are most likely trying to configure something that uses dconf but
the DBus session is not aware of the dconf service. The full error you
might get is</p><pre><codeclass="programlisting">error: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name ca.desrt.dconf was not provided by any .service files
</code></pre><p>or</p><pre><codeclass="programlisting">error: GDBus.Error:org.freedesktop.systemd1.NoSuchUnit: Unit dconf.service not found.
</code></pre><p>The solution on NixOS is to add</p><pre><codeclass="programlisting nix">programs.dconf.enable = true;
</div><divclass="section"><divclass="titlepage"><div><div><h2id="_how_do_i_install_packages_from_nixpkgs_unstable"class="title"style="clear: both">How do I install packages from Nixpkgs unstable? </h2></div></div></div><p>If you are using a stable version of Nixpkgs but would like to install
</code></pre><p>should work provided you have a Nix channel called <codeclass="literal">nixpkgs-unstable</code>.</p><p>You can add the <codeclass="literal">nixpkgs-unstable</code> channel by running</p><pre><codeclass="programlisting shell">$ nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs-unstable
$ nix-channel --update
</code></pre><p>Note, the package will not be affected by any package overrides,
</div><divclass="section"><divclass="titlepage"><div><div><h2id="_how_do_i_change_the_package_used_by_a_module"class="title"style="clear: both">How do I change the package used by a module? </h2></div></div></div><p>By default Home Manager will install the package provided by your chosen
<codeclass="literal">nixpkgs</code> channel but occasionally you might end up needing to change
this package. This can typically be done in two ways.</p><divclass="orderedlist"><olclass="orderedlist "type="1"><liclass="listitem"><p>If the module provides a <codeclass="literal">package</code> option, such as
<codeclass="literal">programs.beets.package</code>, then this is the recommended way to
for more information on package overrides. Alternatively, if you want
to use the <codeclass="literal">beets</code> package from Nixpkgs unstable, then a configuration like</p><pre><codeclass="programlisting nix">{ pkgs, config, ... }:
</code></pre><p>should work OK.</p></li><liclass="listitem"><p>If no <codeclass="literal">package</code> option is available then you can typically change
<aclass="link"href="https://nixos.org/nixpkgs/manual/#chap-overlays"target="_top">overlay</a>.</p><p>For example, if you want to use the <codeclass="literal">programs.skim</code> module but use
the <codeclass="literal">skim</code> package from Nixpkgs unstable, then a configuration like</p><pre><codeclass="programlisting nix">{ pkgs, config, ... }: