CLI tool
dhall-lang/dhall-lang avatar
dhall-lang/dhall-lang

dhall-lang/dhall-lang: the standard, test suite and Prelude behind Dhall

Maintainable configuration files

4,485 stars184 forksDhallBSD-3-Clause

At a glance

What is it?
This repository is not the Dhall interpreter you install to convert config files. It holds the language standard, the standard test suite, the Prelude, and the NixOps specification for the ecosystem's shared infrastructure.
Who is it for?
Adopt this repository only if you are writing or maintaining a Dhall language binding, or if you need to read the formal semantics to settle a question about evaluation. End users who just want JSON or YAML output should install the dhall-to-json and dhall-to-yaml executables instead, which the README points to as the easiest way to start.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Dhall, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What dhall-lang/dhall-lang actually contains, and who needs it

The README opens with a one-line description of the language itself: Dhall is "a programmable configuration language optimized for maintainability," which the README summarizes as JSON plus functions plus types plus imports. That description belongs to Dhall the language. The repository you are looking at is a different artifact. It holds language-independent functionality: the grammar and formal semantics under standard/, a standard test suite under tests/, the Prelude, and a NixOps specification of the shared infrastructure under nixops/.

That split matters when you decide whether to adopt it. Dhall has multiple implementations so that configuration files can be understood natively by several programming languages, and this repository is where the specification those implementations follow lives. If you write configuration in Dhall, you will normally touch a binding or a command line tool, not this tree. If you implement Dhall in a new host language, or maintain an existing binding, this repository is the reference you are measured against. The README is explicit that bindings follow the specification "in order to ensure portability of Dhall configuration files across language bindings." Portability across bindings is the promise; this repository is how that promise is enforced.

The non-Turing-complete design and what it buys

The README states plainly that Dhall is programmable but not Turing-complete, and that many language features take advantage of this restriction to provide stronger safety guarantees and more powerful tooling. The design philosophy section lists the priorities in descending order: polish, simplicity, beginner-friendliness, robustness, consistency. Robustness is described in absolute terms, that the language should never hang or crash.

The README also anticipates the usual objections to programmable configuration and answers them one by one. Against the objection that config files should not be Turing-complete, it answers that evaluation always terminates, no exceptions. Against the objection that abstraction makes configuration unreadable, it answers that every Dhall configuration file can be reduced to a normal form that eliminates all abstraction and indirection. Against the objection that users will run wild with syntax, it answers that the language is minimal, giving the example that you cannot even compare strings for equality.

That last example is worth pausing on, because it is the clearest statement of the trade-off. A configuration language that cannot compare two strings for equality will frustrate anyone who wants conditional logic over string values. The README frames the omission as deliberate, part of forcing users to keep things simple. Read it as a constraint you accept, not a gap that will be filled.

Getting started with dhall-to-json and dhall-to-yaml

The README does not document a build of this repository. What it does say is that the easiest way to start experimenting with Dhall is to install the dhall-to-json and dhall-to-yaml executables, which generate JSON and YAML on the command line, and that platform- and runtime-specific installation instructions live in the Dhall documentation's dhall-json tutorial. So the first step is not cloning this repository; it is installing one of those executables by the route documented for your platform. The README gives no command line invocation for either executable, so the exact flags and input conventions are not specified here and have to come from that tutorial.

What the README does give is the shape of the language you will be writing, and the surrounding documentation it points to. For a short introduction it names Learn Dhall in Y minutes; for core language features it names the Core language features page; for a longer hands-on walkthrough it names the getting started page titled Generate JSON or YAML; and for a condensed reference it names the Dhall cheatsheet. If you want to try the language without installing anything, the README gives the official website, dhall-lang.org, as a live in-browser option.

The framing to keep in mind is that Dhall is JSON plus functions plus types plus imports. The conversion to JSON or YAML is the point of entry rather than a side feature, and the README treats the two executables as the recommended first thing to install. Everything after that is a matter of which of the linked tutorials you follow.

The Prelude is versioned with the standard, not separately

One Dhall package, the Prelude, is versioned with and distributed alongside the language standard, and it lives in this repository under Prelude/. The README describes it as containing general-purpose utilities. That coupling is unusual and worth understanding before you plan upgrades.

In most ecosystems a standard library and a language standard move independently, and you can pin one without the other. Here the README states the opposite: the Prelude is versioned with the standard. The practical consequence is that a change to the Prelude is a change to the thing bindings are tested against, and the standard test suite and the Prelude travel together. If you maintain a binding, you cannot treat Prelude updates as an optional extra you get to later. If you consume Dhall through a binding, the version of the Prelude you get is tied to the version of the standard that binding implements.

The README does not describe a separate release cadence or deprecation policy for the Prelude. The versioning document under standard/ is where the README says the current version and versioning policy are detailed, and the Changelog is where it says you can see the latest changes. Those two files are the place to look before you assume a Prelude change is additive.

The standard test suite is the part that constrains binding authors

The tests/ directory holds a test suite that language bindings can use to check compliance against the standard. This is the mechanism that makes the portability claim testable rather than aspirational. A binding that passes the suite is, by the repository's own definition, conformant.

The limitation here is one of scope. The README says bindings can use the suite, not that they must, and it does not describe a certification process, a registry of conformant bindings, or a badge. Nothing in the README says what happens when a binding fails part of the suite, or how divergences are reported. If you are choosing a binding for production use, the test suite gives you a way to check conformance yourself, but the repository does not appear to publish the results for you. The README's language support page, linked from the integration guide, is where the list of bindings lives; the suite is the tool you bring to that list.

The suite also inherits the standard's version. A binding that passes against one version of the standard may not pass against the next, which is why the versioning document matters more than the test count. The README does not state how often the standard changes, only that the language "slowly evolves in response to user feedback" and that CONTRIBUTING.md describes how to participate in that process.

Where Dhall is the wrong tool, and what Nickel does differently

Dhall is the wrong choice when your configuration needs to compute over strings. The README's own example is that you cannot compare strings for equality. If your config has to branch on whether an environment name equals "prod", Dhall will not let you express that directly. You either restructure so the branch is on a typed value, or you move the decision into the host language that consumes the generated JSON. The README's design philosophy makes this explicit: let the host language that you bind to compensate for any missing features from Dhall. That is a clean separation, but it means Dhall is not a general scripting language wearing a config file's clothes, and anyone expecting one will be disappointed.

The natural alternative to look at is Nickel, which appears in the related searches alongside Dhall. Nickel takes a different position on the same problem: it is a configuration language with a gradual type system and contracts, and it does not impose Dhall's non-Turing-complete restriction in the same way. The difference in approach is where the guarantee comes from. Dhall gets its termination guarantee from the language being total by construction, and pays for it with the missing operations the README lists. A language that keeps those operations has to get its safety from types and contracts checked at evaluation time instead. Neither approach is strictly better; they fail in different places. Dhall fails early, at the point where you try to write an operation the language does not have. The alternative can fail later, when a contract violation surfaces on a value the types did not constrain. If your team values being stopped at authoring time over expressiveness, Dhall's restriction is the feature. If you need the expressiveness, pick the other one and accept the different failure mode.

Maintenance, versioning and licence

The repository is not archived, and the last push was on 2026-09-16. The most recent release listed is v23.1.0 from 2025-01-16, preceded by v23.0.0 from 2023-04-15 and v22.0.0 from 2022-01-24. Those gaps are the honest picture of upgrade cost: major versions have arrived roughly every one to two years, and the jump from v23.0.0 to v23.1.0 came about twenty-one months after v23.0.0. If you maintain a binding, plan for a standard revision on that order rather than a steady monthly trickle.

The README directs you to standard/versioning.md for the current version and the versioning policy, and to CHANGELOG.md for the latest changes. It does not describe a migration guide, a compatibility window, or a deprecation schedule for the standard itself. That means the versioning document is not optional reading before an upgrade; it is the only stated source for how compatibility is defined.

The licence is BSD-3-Clause, per the LICENSE file at the repository root. BSD-3-Clause is a permissive licence, which generally means you can use, modify and redistribute the work, including in closed products, provided the copyright notice and disclaimer are retained and you do not use contributor names to endorse your derivative. That is a general description of the licence family, not legal advice, and the LICENSE file is the text that governs. If you are embedding the Prelude or the test suite in a commercial product, read LICENSE and standard/versioning.md together, because the Prelude's coupling to the standard is the part that affects what you are actually redistributing.

Editorial conclusion

Adopt this repository only if you are writing or maintaining a Dhall language binding, or if you need to read the formal semantics to settle a question about evaluation. End users who just want JSON or YAML output should install the dhall-to-json and dhall-to-yaml executables instead, which the README points to as the easiest way to start. Before committing to a binding, verify three things: which version of the standard your implementation currently targets, whether your binding passes the tests directory, and how the versioning document in standard/ defines compatibility. The repository was last pushed on 2026-09-16, and the most recent release listed is v23.1.0 from 2025-01-16.

Frequently asked questions

What is the Dhall language?

Dhall is a programmable configuration language optimized for maintainability, which the README summarizes as JSON plus functions plus types plus imports. It is not Turing-complete, so evaluation always terminates, and every configuration file can be reduced to a normal form that removes abstraction and indirection.

Is dhall-lang/dhall-lang the same thing as the Dhall language?

No. This repository holds the language-independent parts: the grammar and formal semantics under standard/, the standard test suite under tests/, the Prelude, and a NixOps specification of shared infrastructure. The language has multiple implementations, and the README says this repository is where the specification those bindings follow lives.

How do I install Dhall and convert a file to JSON?

The README says the easiest way to start is to install the dhall-to-json and dhall-to-yaml executables, with platform-specific instructions in the dhall-json tutorial. This repository does not document a build for that; you get the executables from the documentation it links to.

Why can't I compare two strings for equality in Dhall?

The README gives string equality as its example of how minimal the language is, alongside the statement that Dhall forbids many common operations in order to force users to keep things simple. The design philosophy says the host language you bind to should compensate for features Dhall omits.

What is the best configuration language?

The README does not rank configuration languages against each other, so there is no answer here. It states Dhall's own priorities in descending order as polish, simplicity, beginner-friendliness, robustness and consistency, which is the standard it asks to be judged by.

Official sources

  1. dhall-lang/dhall-lang on GitHub
  2. License: BSD-3-Clause
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dhall-lang-dhall-lang.svg)](https://hysenlabs.com/projects/dhall-lang-dhall-lang)