<section xmlns="http://docbook.org/ns/docbook"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         version="5.0"
         xml:id="sec-custom-packages">
 <title>Adding Custom Packages</title>

 <para>
  It’s possible that a package you need is not available in NixOS. In that
  case, you can do two things. First, you can clone the Nixpkgs repository, add
  the package to your clone, and (optionally) submit a patch or pull request to
  have it accepted into the main Nixpkgs repository. This is described in
  detail in the <link
xlink:href="https://nixos.org/nixpkgs/manual">Nixpkgs
  manual</link>. In short, you clone Nixpkgs:
<screen>
<prompt>$ </prompt>git clone https://github.com/NixOS/nixpkgs
<prompt>$ </prompt>cd nixpkgs
</screen>
  Then you write and test the package as described in the Nixpkgs manual.
  Finally, you add it to <literal>environment.systemPackages</literal>, e.g.
<programlisting>
<xref linkend="opt-environment.systemPackages"/> = [ pkgs.my-package ];
</programlisting>
  and you run <command>nixos-rebuild</command>, specifying your own Nixpkgs
  tree:
<screen>
# nixos-rebuild switch -I nixpkgs=/path/to/my/nixpkgs</screen>
 </para>

 <para>
  The second possibility is to add the package outside of the Nixpkgs tree. For
  instance, here is how you specify a build of the
  <link xlink:href="https://www.gnu.org/software/hello/">GNU Hello</link>
  package directly in <filename>configuration.nix</filename>:
<programlisting>
<xref linkend="opt-environment.systemPackages"/> =
  let
    my-hello = with pkgs; stdenv.mkDerivation rec {
      name = "hello-2.8";
      src = fetchurl {
        url = "mirror://gnu/hello/${name}.tar.gz";
        sha256 = "0wqd8sjmxfskrflaxywc7gqw7sfawrfvdxd9skxawzfgyy0pzdz6";
      };
    };
  in
  [ my-hello ];
</programlisting>
  Of course, you can also move the definition of <literal>my-hello</literal>
  into a separate Nix expression, e.g.
<programlisting>
<xref linkend="opt-environment.systemPackages"/> = [ (import ./my-hello.nix) ];
</programlisting>
  where <filename>my-hello.nix</filename> contains:
<programlisting>
with import &lt;nixpkgs> {}; # bring all of Nixpkgs into scope

stdenv.mkDerivation rec {
  name = "hello-2.8";
  src = fetchurl {
    url = "mirror://gnu/hello/${name}.tar.gz";
    sha256 = "0wqd8sjmxfskrflaxywc7gqw7sfawrfvdxd9skxawzfgyy0pzdz6";
  };
}
</programlisting>
  This allows testing the package easily:
<screen>
<prompt>$ </prompt>nix-build my-hello.nix
<prompt>$ </prompt>./result/bin/hello
Hello, world!
</screen>
 </para>
</section>
