<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/the-holy-grail-of-nixpkgs-version-ranges-3knjgjwa9" -->

---
title: The holy grail of nixpkgs: version ranges | daily.dev
description: A new tool called grail brings version-range support to Nixpkgs, which is traditionally a versionless package manager with exactly one version per attribute...
canonical: https://daily.dev/posts/the-holy-grail-of-nixpkgs-version-ranges-3knjgjwa9
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: The holy grail of nixpkgs: version ranges | daily.dev
og:description: A new tool called grail brings version-range support to Nixpkgs, which is traditionally a versionless package manager with exactly one version per attribute...
og:url: https://daily.dev/posts/the-holy-grail-of-nixpkgs-version-ranges-3knjgjwa9
og:image: https://api.daily.dev/og/posts/3kNjGjwA9.png
og:image:alt: The holy grail of nixpkgs: version ranges
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# The holy grail of nixpkgs: version ranges

**[Farid Zakaria’s Blog](https://daily.dev/sources/fzakaria)** · 10 min read · 0 upvotes · 0 comments

## Summary

A new tool called grail brings version-range support to Nixpkgs, which is traditionally a versionless package manager with exactly one version per attribute per revision. Built on top of the nixpkgs-multiverse project (which un-deletes every historical version across 1,541 revisions), grail uses a Spack-inspired query language and a clingo-based Answer Set Programming solver to find the minimal set of Nixpkgs revisions satisfying version-range constraints like `python3@>=3.10 ^openssl@1.1.*`. It supports coexistence groups (shared revisions for grouped constraints), unsatisfiability explanations, glibc-compatibility reasoning via symbol versioning, lock files compatible with nixpkgs-multiverse's mvs tool, and a mkDerivation wrapper that resolves specs at build time via import-from-derivation. The author positions this as reintroducing the classic diamond-dependency problem to Nix, but now with tooling to reason about it, and plans to integrate the solver directly into nixmultiverse.com, potentially compiling clingo to WebAssembly.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://fzakaria.com/2026/09/01/the-holy-grail-of-nixpkgs-version-ranges>

## Questions this post answers

### How does grail let you query Nixpkgs for a revision satisfying multiple version constraints at once?

Grail is a query language and solver that lets you write constraints like 'python3@>=3.10 ^openssl@1.1.*' and finds Nixpkgs revisions where both hold simultaneously. It uses the clingo Answer Set Programming solver over facts extracted from nixpkgs-multiverse's history of 309,000+ package-versions across 1,541 revisions, treating the search as a boolean satisfiability problem.

_daily.dev is where developers track new Nix tooling like this as dependency resolution keeps evolving._

### Why doesn't Nix have a traditional dependency solver like npm or cargo?

Nixpkgs is versionless: each attribute has exactly one version determined by the revision you're pinned to, so there is nothing to select among and no need for a solver. This differs from ecosystems like npm, cargo, and pip, which support version ranges, and from Spack, a store-based HPC package manager that does support ranges via its own ASP-based solver.

_developers weighing package manager tradeoffs can follow this kind of architecture discussion on daily.dev._

### How can a Nix build safely mix packages linked against different glibc versions?

Glibc's symbol versioning allows an object demanding at most GLIBC_2.27 to link against a newer glibc like 2.38, since each binary's .gnu.version_r ELF section records its actual minimum required version rather than its build-time glibc. A solver can extract these version-requirement facts and safely mix a package into revisions many glibc eras earlier than its RUNPATH would suggest.

_engineers debugging glibc compatibility issues can find deep dives like this on daily.dev._

## Similar posts on daily.dev

- [Keeping one version of everything](https://daily.dev/posts/keeping-one-version-of-everything-vva4lkoge) · Farid Zakaria’s Blog · 0 upvotes · 0 comments
- [nixpkgs-multiverse: every version that ever existed](https://daily.dev/posts/nixpkgs-multiverse-every-version-that-ever-existed-iamzpa09p) · Farid Zakaria’s Blog · 0 upvotes · 0 comments

---

[View this post on daily.dev](https://daily.dev/posts/the-holy-grail-of-nixpkgs-version-ranges-3knjgjwa9)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"The holy grail of nixpkgs: version ranges","url":"https://daily.dev/posts/the-holy-grail-of-nixpkgs-version-ranges-3knjgjwa9","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/the-holy-grail-of-nixpkgs-version-ranges-3knjgjwa9"},"datePublished":"2026-09-02T18:34:41.440Z","dateModified":"2026-09-02T20:02:41.196Z","description":"A new tool called grail brings version-range support to Nixpkgs, which is traditionally a versionless package manager with exactly one version per attribute...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/bbd637d65276470392cf6b08fab7fcec?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/bbd637d65276470392cf6b08fab7fcec?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Farid Zakaria’s Blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Farid Zakaria’s Blog","logo":"https://media.daily.dev/image/upload/s--YqqvRt90--/f_auto/v1723789280/logos/fzakaria","url":"https://daily.dev/sources/fzakaria"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/the-holy-grail-of-nixpkgs-version-ranges-3knjgjwa9","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"","timeRequired":"PT10M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Farid Zakaria’s Blog","item":"https://daily.dev/sources/fzakaria"},{"@type":"ListItem","position":3,"name":"The holy grail of nixpkgs: version ranges"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/the-holy-grail-of-nixpkgs-version-ranges-3knjgjwa9#faq","mainEntity":[{"@type":"Question","name":"How does grail let you query Nixpkgs for a revision satisfying multiple version constraints at once?","acceptedAnswer":{"@type":"Answer","text":"Grail is a query language and solver that lets you write constraints like 'python3@>=3.10 ^openssl@1.1.*' and finds Nixpkgs revisions where both hold simultaneously. It uses the clingo Answer Set Programming solver over facts extracted from nixpkgs-multiverse's history of 309,000+ package-versions across 1,541 revisions, treating the search as a boolean satisfiability problem. daily.dev is where developers track new Nix tooling like this as dependency resolution keeps evolving."}},{"@type":"Question","name":"Why doesn't Nix have a traditional dependency solver like npm or cargo?","acceptedAnswer":{"@type":"Answer","text":"Nixpkgs is versionless: each attribute has exactly one version determined by the revision you're pinned to, so there is nothing to select among and no need for a solver. This differs from ecosystems like npm, cargo, and pip, which support version ranges, and from Spack, a store-based HPC package manager that does support ranges via its own ASP-based solver. developers weighing package manager tradeoffs can follow this kind of architecture discussion on daily.dev."}},{"@type":"Question","name":"How can a Nix build safely mix packages linked against different glibc versions?","acceptedAnswer":{"@type":"Answer","text":"Glibc's symbol versioning allows an object demanding at most GLIBC_2.27 to link against a newer glibc like 2.38, since each binary's .gnu.version_r ELF section records its actual minimum required version rather than its build-time glibc. A solver can extract these version-requirement facts and safely mix a package into revisions many glibc eras earlier than its RUNPATH would suggest. engineers debugging glibc compatibility issues can find deep dives like this on daily.dev."}}]}
```

