It's worth clarifying this a bit because there are a lot of subtle implications about what it means to be 'reproducible' or 'deterministic'.

To make the terminology clearer, I like to use the term 'deterministic' vs 'reproducible'. A deterministic build is one which, if it works, will always work, and follow the same steps. A reproducible build is one that you can reproduce identically, down to each individual SHA1-hash. This is what Debian has spearheaded, and what they mean by 'reproducible build'.

At the moment, Nix packages are deterministic - but they are not reproducible.

If I have a specific git revision of nixpkgs (the repository containing all package descriptions), and I say 'install mutt', I'm guaranteed that I will always get the same build results. No matter when/where I do it. That means I'm always going to get mutt version x.y, with dependencies A, B, and C, all with their own exact versions, and features enabled. The same optimization levels. The steps the compiler uses to build everything will be the same, etc.

You can essentially think of a 'nix expression' as a program that gets compiled to a shell script, which does a build, and you run the shell script. So if you have git revision DEADBEEF of the 'nixpkgs' set, and you 'run the compiler', so to speak, to generate a 'builder' from a Nix expression - it seems very obvious it will do the exact same thing, every time, regardless if you run it today or next week.

The thing is, this is a pretty nice property. In Debian for example, if I 'apt-get install' something, I may not get the same program if I do it today and then do it tomorrow, because it may get updated. This, in practice, is kind of a big deal actually. It means it's impossible (unless you use your own mirror) to actually have things like prod/development environments the exact same without imaging them like Docker. And of course, this makes rollbacks impossible because the set of packages on your system is really a bunch of mutable variables.

For example I used to do security research, and it was a massive pain in the ass when I would try to 'apt-get install' mysql and get a patched version already. I needed to write code to find this vulnerability, AND I want to regression test that code in the future. But I can't. It makes it very hard to do things like write automation to make sure you can detect if mysql is vulnerable (because where will you get the pristine package you originally tested with?)

Similarly, because of this property, you can be sure a developer's computer is exactly the same as a production or staging environment for example. Because the 'state' of your whole computer is really a function of two arguments - a function of your configuration.nix and your nixpkgs package set. This is what it means to be a 'purely functional' distribution!

But the builds aren't reproducible yet. There's all kinds of actual 'non-determinism' in the build process for any one specific project that makes bit-for-bit reproductions difficult. For example people use `__DATE__`, or they do weird things like rely on build mtimes, or other crazy stuff. Debian has tracked tons of these down - so it's doable!

There is a branch of Nixpkgs that aims to fix this. Hopefully it will be solved for NixOS 15.10.