Install Nix
-
Install Nix (Single-user installation)
sh <(curl -L https://nixos.org/nix/install) --no-daemon
-
Enable flakes
-
Set
show-trace = true
(doc) to see more complete error messages.
Community
Nix messages
Sometimes, when you enter a devshell (e.g., nix develop
) or run a default package of a flake, you may see:
- warnings - not a problem, just read them and google if you're interested;
- errors - the same story;
- prompts - answer
y
(the simplest way).
direnv
This is a tool for running scripts when you cd
to a directory containing a .envrc
file.
direnv
automatically builds, caches, and starts a devshell when you enter a flake directory containing the .envrc
file (e.g., the root directory of this repository).
See Direnv integration.
-
Install
direnv
- src-
Install the binary
nix profile install nixpkgs#direnv
-
Hook into your devshell
-
-
Allow
direnv
to work in a directory.direnv allow
When you see
direnv
errors, run the suggested commands.
Further reading
See Nix prerequisites.
Nix Prerequisites
Install Nix
- Complete all steps from here
Community
Resources
- Study the
Nix
language - Learn about flakes
- Read:
- Nix manual
- Nix glossary
- nixpkgs manual
- nix.dev - Good tutorials. No flakes so far
- NixOS/Learn
- Watch
References
I added bookmarks for search engines in my browser, like described here.
- nix-lib - Nix (builtins) & Nixpkgs (lib) Functions
- Nixpkgs manual
- devdocs - search functions
- grep nixpkgs
- grep nixpkgs on GitHub
Docs
Nix repl
Docs are usually left as comments in Nix
code. You can find an attribute in nix-repl and look up its comments in a file at a given position.
nix repl
nix-repl> :lf nixpkgs
nix-repl> legacyPackages.x86_64-linux.lib.lists.singleton
«lambda @ /nix/store/24akvz6idhp4lxxvhbfxxq84py30v6bw-source/lib/lists.nix:23:15»
Sometimes, you may evaluate a description
or a longDescription
of a derivation:
nix-repl> legacyPackages.x86_64-linux.coreutils.meta.longDescription
"The GNU Core Utilities are the basic file, shell and text manipulation\nutilities of the GNU operating system. These are the core utilities which\nare expected to exist on every operating system.\n"
nix commands
Learn about a command:
nix help command
Search for a package description:
nix edit nixpkgs#coreutils
Flake templates
List templates
If a flake.nix
contains a valid output templates
, these templates can be listed.
List flake outputs and search for templates
in this (flakes
) repository:
nix flake show | grep template
└───templates
evaluating '' ├───codium-generic: template: `VSCodium` with extensions and executables
├───codium-haskell: template: `VSCodium` with extensions and executables for `Haskell`. Shows 5 ways to run a `Haskell` app.
evaluating '' ├───codium-haskell-simple: template: `VSCodium` with extensions and executables for `Haskell`.
evaluating '' ├───codium-python: template: `VSCodium` with extensions and executables for `Python`.
└───haskell-minimal: template: Minimal flake for a `Haskell` package development.
Use a template
Two ways of copying from templates:
Update a cached template
If you notice that nix flake init
, nix flake new
, etc. give you an old version of a template, run nix flake lock
on that template. This action will force nix
to update the cached version of the template somewhere in ~/.cache/nix
. - src
Explore a template
Templates can be accessed in Nix store via nix repl
:
nix repl
nix-repl> :lf .
nix-repl> templates.<TAB>
nix-repl> templates.codium-generic.path
/nix/store/j3kx4dk567y483pvszr2w8ghnkxich3d-source/templates/codium/generic
Assemble
Templates may contain arbitrary files. This feature enables the following assembly:
nix flake new flake-1 -t flake1
nix flake new flake-2 -t flake2
nix flake new flake-3 -t flake3
cp flake-1/file1 flake-3
cp flake-2/file{2,3} flake-3
Template repositories
Flakes
-
What are flakes? How to enable flakes? - wiki
-
Nix manual answers the following questions:
- Glossary
- What does this term mean?
- Derivations
- What are derivations?
- Something that describes how to create a particular
Nix
store path - A
derivation
can become an executable, and that executable can be used in build scripts of other derivations
- Something that describes how to create a particular
- What are derivations?
- Description
- What are flakes?
- A flake is a function from inputs into outputs. To take this function at a point, a
flake.lock
is used - Don't confuse 'inputs' and 'outputs' with the terms
inputs
andoutputs
. - I use 'inputs' and 'outputs' to describe the high-level idea of what a flake is.
- On the other hand,
inputs
andoutputs
have specifications described in Nix manual.
- A flake is a function from inputs into outputs. To take this function at a point, a
- What are flakes?
- Flake inputs:
- How to use old-style packages as flake inputs?
- How to declare an input? == How to use a flake in another flake?
- How to follow an input?
- How to pin an input?
- Flake format
- What can go into
outputs
? - How to access the
outputs
? (described at the bottom) - How can I override nix.conf? - via
nixConfig
- What can go into
- Experimental commands
- How to explore a flake?
nix flake show
nix flake metadata
nix repl
nix-repl> :lf nixpkgs
- load flakenixpkgs
- How to see all
derivation
s used to build a specificderivation
?nix show-derivation
- How can I temporarily make an executable available in my terminal?
nix shell
- How can I install a Nix package on my OS?
nix profile
- How can I pin my global
nixpkgs
to a specific commit SHA?nix registry
- How to explore a flake?
- And many more questions!
- Glossary
-
How to add a flake to a project?
- Nix uses
git
to track flake files. So, adding aflake.nix
to a project requires the following steps:git init
- initialize agit
repository- Add
flake.nix
in some way (copy the existingflake.nix
,nix flake init
, etc.) git add flake.nix
- Add
flake.lock
in some way (copy the relevant existingflake.lock
, generate a new one vianix flake update
, etc.) git add flake.lock
git commit
these files
- Nix uses
-
How to use the same flake inputs in all projects?
-
How to bring any files into a flake?
- Hack git
- List expected files.
- Commit corresponding blank files.
- Run
git update-index --assume-unchanged <file>
for each<file>
. - Now, it's possible to import them into flake.
- Use Fixed-output derivations (FOD)
- Hack git
-
How to enable a specific version of
nix
on my system? Approximately so:nix registry remove nix nix registry add nix github:NixOS/nix/4bf70b74a78bf10f3f19ed122ae7377963e14003 nix profile install nix --priority 4
-
How to pin
nixpkgs
? -
When should I use overlays over
nixpkgs
? - You shouldn't -
How to convert an exising project to flakes? - tutorial
-
How to use a
.gitignore
d file inside a flake?-
build with
--impure
zxcTest = prev.writeText "zxcTest" (builtins.readFile /home/name_snrl/nixos-configuration/<fileFromIgnore>);
-
Provide it in inputs. Inputs accept arbitrary files. Make links follow the format of flake inputs
-
-
How to disable querying remote binary caches?
nix run <installable> --no-substitute
devShells
- How to set up a development environment?
2.
pkgs.mkShell
3. devshell 4. Add environment variables if necessary. E.g., using Nix store paths post 5. Symlink a path from Nix store to make files available toNodeJS
- NixOS: The Ultimate Dev Environment?
Nix
Nix store caching
- cachix
- Attic
- cache-nix-action - save and restore cache in
GitHub Actions
- nix-serve - serve nix store as a binary cache
- to check if a package is in store, use curl
Q&A
-
Run a binary from
nixpkgs
:nix run nixpkgs#nixpkgs-fmt -- hello-flake/flake.nix
Fixed-output derivation
Making derivations and executables
-
What is
expression
,closure
,derivation
?- Check the glossary
- expression, closure, derivation
-
How to get a path of a derivation in store in a
.nix
file?:${drv}
-
There are phases
-
When derivations are built, they may produce executables. Locations of these executables are determined by bash scripts. If you make a derivation you can use
buildInputs
to specify the derivations you'd like to be accessible during in scripts duringphases
or in ashellHook
-
How to access a
$out
folder of a derivationdrv
?- First of all, you should create such folder, e.g. via a builder
- Alternatively, it will be created during the install phase
- Next, you can use it in a script like
${drv.out}
;
- First of all, you should create such folder, e.g. via a builder
-
Programs can be specified in
buildInputs
or called by name{pkgs.hello}/bin/hello
- This helped me when configuring tasks for VSCodium here
-
How to wrap an executable to run it with flags?
- See the example with
pkgs.runCommand
in Wrapping Packages - Another example in language-tools/haskell
- See the example with
-
How to rename an executable and supply runtime dependencies?
- symlinkJoin +
wrapProgram
provided bypkgs.makeBinaryWrapper
(docs, src).
hello = pkgs.symlinkJoin { name = "hello"; paths = [ hello ]; buildInputs = [ pkgs.makeWrapper ]; postBuild = '' wrapProgram $out/bin/hello \ --set PATH ${ pkgs.lib.makeBinPath [ pkgs.cowsay ] } ''; };
- symlinkJoin +
-
How to escape a shell/bash command? 2.
pkgs.lib.escapeShellArg
-
How to see binaries that a package provides? 2.
find $(nix build nixpkgs#hello --no-link --print-out-paths)/bin -mindepth 1
-
It's possible to use
nix
commands inside scripts- E.g.
nix-instantiate --eval --strict -E "import ./settings.nix"
- print contents of a nix file - Moreover, one can use pinned
nixpkgs
:nix run ${pkgs}#nixpkgs-fmt $nix_path
- E.g.
-
How to package a script? 2. pkgs.writeScriptBin
-
How to remove build deps from runtime deps?
- see this pill
-
How to use parallel builds? - docs
Helper function libs
-
- Whenever possible, add a flake into a repo, and then use
flake-compat
to createdefault.nix
andshell.nix
- Use it to access scripts from a flake in a child directory - example
- Whenever possible, add a flake into a repo, and then use
-
nixpkgs.lib
$ nix repl nix-repl> :lf nixpkgs nix-repl> lib.or true false
-
Symlinked things cannot be written or opened. They should first be removed - src
-
pkgs.dockerTools.buildLayeredImage
- build a docker image- Pass static executables
- Set entrypoint:
config.Entrypoint = [ command ]
. No need forbash
docker inspect
the image
Package code
Haskell
See Haskell
Python
TypeScript
PureScript
- spago.nix
- TODO try
Conventions
READMEs
In this repo, each flake's README.md
assumes that the directory of its flake.nix
is your current working directory in a terminal.
Prerequisites
To de-duplicate the docs, one of the top sections of each README.md
here contains a Prerequisites
section. This section provides the links to other sections that possibly contain the relevant docs. Sometimes, you'll need to traverse multiple Prerequisites
before you achieve the relevant docs.
nixConfig
I inserted a number of binary caches into nixConfig
attribute of each flake.nix
.
These caches should accelerate builds.
You can add an accept-flake-config to your nix.conf.
Dev tools
Sometimes, I put dev tools into a nix-dev
directory.
Then, I enter a devshell as follows.
nix develop nix-dev/
Pushing to a remote repo
All flakes in this repo access some other flakes from this repo via GitHub
URLs.
Let's consider two flakes from this repo, A
and B
, where A
is in inputs
of B
.
If I change the flake A
, I:
- push
A
changes to GitHub. - update
flake.lock
ofB
.
Whenever there's a push to the remote GitHub
repo, B
's flake.lock
is updated by a GitHub Action
.
That's why, if that action works, there's no need to commit and push flake.lock
changes.
After an update is complete, it's necessary to rebase local changes onto remote changes.
However, sometimes, there are local uncommitted changes already.
These changes should be git stash
ed before doing git rebase
.
After rebasing, they can be git stash pop
ped to continue the work.
Thus, the process is as follows:
# can be omitted in case of automatic fetches
git fetch
git rebase --autostash
git push
Docs
Each derivation that evaluates to an executable should have these attributes:
meta.description
- string written in
CommonMark
- This description will be rendered in devshells
- It should be a single-line brief description of this executable
- string written in
meta.longDescription
- string written in
CommonMark
- This description is used to generate
man
pages for executables - The format of a
longDescription
should be recognizable bypandoc
- Here's a sample input
- string written in
Troubleshooting
Prerequisites
Red text in the output
This is not a problem. Just read the text and answer. When asked like:
do you want to allow configuration setting 'extra-trusted-substituters' to be set to 'https://haskell-language-server.cachix.org https://nix-community.cachix.org https://cache.iog.io https://deemp.cachix.org' (y/N)?
answer y
.
And then, when asked
do you want to permanently mark this value as trusted (y/N)?
answer y
again. This is to let you use the binary caches listed by the flake.
VSCodium troubleshooting
Substituters and keys
To provide binary caches, flake.nix
files specify nixConfig.extra-trusted-substituters
. If you try, e.g., nix develop
, and Nix
unsuccessfully tries to download from a cache several times, this cache has probably failed. Comment out the lines containing its URL
address in extra-trusted-substituters
.
Repair a derivation
Repair a derivation - manual
Alternative steps:
- Assumptions:
- current working directory contains
flake.nix
- your corrupt derivation is available inside this
flake.nix
by . nameyour-corrupt-derivation
- current working directory contains
- Set
packages.default = your-corrupt-derivation
in thisflake.nix
- Run
nix store repair .#
.#
denotes an installable
Locales
See Locales
Haskell
Templates
Templates provide extensive information about setting up development environment and packaging Haskell apps.
Tools
ghcid
ghcid is a Very low feature GHCi based IDE
.
It can be used to re-run a function in a given file on changes in a given directory.
This template provides a sample configuration for this tool in the .ghcid
file.
hpack
hpack translates package.yaml
into .cabal.
Nix
haskell4nix
- haskell4nix
- nixpkgs manual
- Incrementally package a Haskell program
- haskell-nix - examples of packaging haskell apps
- Nixpkgs support for incremental Haskell builds
- Hackage packages in nixpkgs - Haskell packages
- Fixing broken Haskell packages in Nixpkgs
- Horizon Haskell
haskell.nix
- haskell.nix
- tutorial
- projects: discord-emoji-dl
Stack
Uses haskell4nix.
Stack support Nix integration.
Stack uses nix-shell.
- docs.
The name of the file providing a Nix shell can be customized in stack.yaml
.
Here's the format of that file - docs.
The shell file can import the contents of flake.nix
via flake-compat.
flake.nix
provides an output stack-shell.${system} = {version}: ...
.
stack.nix
imports flake.nix
and provides a shell.
devShells
Completions for CLI apps
devShells.default = pkgs.mkShell {
buildInputs = [ packageExe ];
shellHook = ''
source ${packageExe}/share/bash-completion/completions/${packageExecutableName}
'';
};
Troubleshooting
Haskell Language Server
Clear cache
Sometimes, HLS
finds errors in code despite cabal build
running successfully.
If you use VS Code
, find Outputs
of Haskell Language Server
and determine the cache directory for a project.
It should have approximately this form: /home/<user name>/.cache/hie-bios/dist-<project-name>-<something>
.
Remove it and restart HLS
.