Where does my user config file live?

I just installed Nix on Ubuntu 18.04. I was mainly attracted to nix for the idea of having a truly pure, declarative package manager. I followed along with the manual, and I can install packages imperatively with eg nix-env -i emacs. But I just can’t figure out where my actual user config file lives… I guess I was expecting a .nix file living somewhere in my home directory that defines my entire config, with nix-env -i modifying that file and applying the changes.

skainswo@skainswo-X58A-UD3R:~$ nix-env -iA nixpkgs.vscode
installing 'vscode-1.45.0'
error: Package ‘vscode-1.45.0’ in /nix/store/15cr0b2cyj50mkcssq5q5k7dqdlzhyka-nixpkgs-20.09pre225898.7319061eef4/nixpkgs/pkgs/applications/editors/vscode/vscode.nix:40 has an unfree license (‘unfree’), refusing to evaluate.

a) For `nixos-rebuild` you can set
  { nixpkgs.config.allowUnfree = true; }
in configuration.nix to override this.

b) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add
  { allowUnfree = true; }
to ~/.config/nixpkgs/config.nix.

(use '--show-trace' to show detailed location information)

seems to indicate that it should live in ~/.config/nixpkgs/config.nix but there’s no nixpkgs directory in ~/.config.

OTOH the cheatsheet indicates that it should be found at ~/.nixpkgs/config.nix but there’s no .nixpkgs directory in my home directory either.

All in all, this is very confusing and it seems as though at least some of this info must be out of date.


Are you asking how to install packages declaratively on a per user basis? nix-env -i installs packages imperatively. For declarative user package management, you should check out home-manager.

The only thing I have in my config.nix (you can create this) is:

{ allowUnfree = true; }

For reference, a minimal home.nix would be

{ config, pkgs, ... }:

with pkgs;

  # Let Home Manager install and manage itself.
  programs.home-manager.enable = true;
  home.packages = [ 

I have a function in my .zshrc for updating packages (similar to apt upgrade)

upgrade () {
  nix-channel --update
  home-manager switch

Happy to help walk you through things more step by step in IRC, matrix, or discord.


Thanks so much for the quick response @mjlbach! This is somewhat disheartening to hear. I was really looking forward to the whole declarative package manger thing. I was expecting it to operate much in the same way that npm install offers a faux-imperative interface to a declarative package.json config. When nix-env operates in this imperative way, where does it store the user’s state?

Thanks for the reference to home-manager! I’ll definitely check that out.

1 Like

I wouldn’t be disheartened, nix is a declarative package manager. On NixOS, configuration.nix defines the entire system state (including packages) declaratively. On non-nixos systems, you could write a default.nix containing all the desired declarative packages and install it with nix-env -i your_package_set. Home-manager abstracts this away for you and provides some nice configuration options. Most people I know that use nix, use home-manager.

For more information on nix-env, check out this section in the nix manual

Yeah unfortunately I can’t go full NixOS yet. Hopefully home-manager gets me close enough. I’m just a little curious why this isn’t the default Nix behavior.

1 Like

FWIW I use nix on Fedora (in addition to NixOS) so I believe it will. You might want to read through:

There’s also discussion on IRC about this in #home-manager, as well as on the github issues for nixos/nixpkgs and rycee/home-manager.

1 Like

I manage my nix-env in a totally declarative way: nix-env has a --replace flag which operates by atomically replacing all previously installed packages with the env you’re asking it to install at that invocation. This allows you to create a workflow where you:

  1. Create a myEnv.nix that has a manifest of packages you want, then
  2. Run nix-env --replace when you install that 1 env.

For me personally, that looks like this:

(I have them split into two envs, since I don’t want to install everything on cloud nodes / transient containers.)

This is a really basic way of doing this with the built-in tools that works for me, but if you’d like to take this idea further, there’s home-manager.


It adds symlinks to binaries in a directory that appears in $PATH.

Short answer: historic reasons. There are a few more instances of these, let’s call them, legacy design decisions for which discussions regularly come up on the forum or in GitHub issues. Another one is the use of environment variables, which confuses the hell out of people if they expect a declarative system to have a self-contained representation in some set of files.

My impression is that most here agree that the nix tools have UI issues which contribute to the steep learning curve and scare off some newcomers.

I think though, you are in the right place for what you are seeking. You‘ll get what you want eventually, you just have to acknowledge the fact that you are an early adopter and will have to put in some effort - unfortunately. I’d like it easier, too, but every time I dig out some project from months ago, or migrate something to a new system, I am amazed and thankful how everything that had to be painstakingly set up Just Works™.

1 Like

Yeah, I really like the spirit of the project. It’s just the UI and documentation seem a little rough-around-the-edges. What’s the best way to participate in these sorts of roadmap discussions besides posting on this forum?

1 Like

I think this is a good question, and as many things here the answer required me some roaming around to be sure.

Most discussions happen here, in GitHub issues, RFCs and the IRC channel.

The web page does not mention GitHub - maybe strategically to separate general and usage discussion from technical and organizational topics.

1 Like