Does the nix expression language have a specification?

I am getting around to fully learning the nix expression language.
I’m curious if it has a specification or detailed implementation documentation.

Do you know of any?

If not, what sources have you used to understand the language in depth?

My hope would be to read a specification to determine whether parsing errors like decimal floats without leading zero causes a parsing failure · Issue #46 · nix-community/rnix-parser · GitHub are correct behavior.


According to this stackoverflow thread there is no formal specification, and currently the ultimate source is the lexer.

On the other hand, there are also the hnix and rnix projects that may have a spec (haven’t checked yet).


I perused the source of hnix, rnix-parser, and nix itself.
I did not find any documentation about the language specification.

hnix actually embed’s a version of the lexer in their doc directory!
rnix-parser seems to be a Rust port of the parsing and lexing.

So I’m making the generalization that the Nix expression language is underspecified. I find it helpful knowing the tradeoffs.

As an aside, I don’t find this problematic. I’d guess that the more formalized nickel will supersede nix expression language someday.


Wanted to suggest an RFC for it but not sure if the reason for the lack of a formal Nix language specification is a deliberate choice or the lack of human-power to keep it maintained.

Totally missed this, thanks!

Thanks for the reminder regarding Nickel; there is also this thread you may be interested in:

(Along with the periodic Tweag + Nix dev updates.)

1 Like

Just wanted to point out that the latest Tvix update mentions work on a specification, which hasn’t been released yet AFAIK:

Finishing our language specification. Based on what we’ve learned, we’re writing a specification of the Nix language that captures its various behaviours in all their tricky subtlety and subtle trickery.


There is also nixel, which is a spec written in rust. According to the docs, it uses the same algorithms as the C++ code, so it should be correct.

Then there is also the tree-sitter grammar which might be a nice high level view of the language. I learned about let {} syntax thanks to this, for example.


let { } syntax? I’ve never seen that. Can you give an example.

let { x = 2; y = 3; body = x + y; } # evals to 5

There is an eval error if the body attribute is not provided, so essentially body is equivalent to an in block.