Nixpkgs' Repology milestone comes from a more complete export
December's repository ranking reflects previously omitted subsets becoming visible, showing how package enumeration affects comparisons.
A repository can appear to gain thousands of packages when its exporter starts including software that was already there. That is the mechanism behind today's report that nixpkgs-unstable has surpassed the AUR in Repology's comparison. The immediate change is a more complete JSON export. The milestone describes improved visibility into the package collection, rather than a single burst of new packaging work.
The December 24 community report says that a few thousand packages in subsets were missing from the file Nixpkgs exported and Repology imported. It links the patch expanding that export. The reported ranking changed after the patch merged and the channel advanced past it. Those steps explain why an existing collection became newly visible to an external comparison.
I like declarative package collections because their structure can expose what is available and how it is built. This example adds a qualification to that preference. An index sees what its enumeration procedure traverses, which can be less than the collection its maintainers have defined.
Attribute structure influences the exported inventory
Nixpkgs organizes some packages within attribute sets. An exporter that visits only selected levels can omit packages inside a subset. The package-index configuration at the patch's final commit explicitly addresses sets that nix-env would not normally explore. Its comment describes the goal as obtaining a more complete picture for the index.
Before this patch, the override marked haskellPackages and rPackages for recursion. The replacement broadens that treatment to a list of subsets. Among them are Node package sets, Roundcube plugins, and Emacs package sets. This changes which existing definitions the export discovers. It does not itself add a build recipe for each newly counted item.
The patch also accounts for package-set names that differ between branches. It filters the candidate list through builtins.hasAttr before retrieving a set. This permits one index configuration to name possible subsets without failing merely because a particular package collection lacks one of them. The filter is a concrete part of making the broader traversal usable.
The configuration then builds an attribute set whose values are the selected subsets marked for recursion. That is a structural operation on the package collection used for indexing. The resulting inventory depends on this configuration in addition to the high-level repository revision. Counting packages therefore requires identifying how the evaluator enumerates them, not merely identifying which repository it evaluates.
Recursion is an explicit marker
The attribute-set library at the same commit defines recurseIntoAttrs by adding a marker to an attribute set. Its core operation is small:
attrs // { recurseForDerivations = true; }
The expression retains the original attributes and adds the recursion flag. Its significance comes from the consumer that interprets that flag when enumerating derivations. This is a convention shared by the package-set representation and the indexing tool. The nested packages can already exist while remaining absent from an inventory that has not been told to recurse into their containing set.
The same library provides an operation that sets the flag to false. The existence of both directions reinforces that traversal is a deliberate choice. An attribute set is not automatically a flat list of installable packages merely because it appears within Nixpkgs. Tooling needs rules for deciding which values to inspect further and which values represent the objects it is trying to count.
This also explains why the patch can be modest while the visible numerical effect is large. One marker applied to a substantial subset changes the discoverability of many definitions. The size of the patch and the number of newly exported entries measure different things. Treating the exported increase as an equal number of newly written recipes would misdescribe the change.
The comparison has a defined population
The report names nixpkgs-unstable and the AUR in Repology's dataset. That is the comparison its evidence supports. It does not establish a count of every software project distributed anywhere, or show that every counted package works on every system. Repository enumeration and successful builds across platforms are different observations.
The export configuration also sets allowAliases = false, with a comment saying this prevents aliases from appearing in results. This is another counting decision visible in the source. An alternative attribute name need not count as an independent package merely because an evaluator can resolve it. The exporter intentionally chooses a population that avoids that particular source of duplication.
There can still be multiple package sets serving distinct purposes. The patch includes both nodePackages and nodePackages_latest, as well as versioned Emacs sets. Their inclusion is part of the published export procedure. The report alone does not explain every normalization rule Repology applies afterward, so it is insufficient evidence for equating raw Nix attribute counts with the final comparison's units.
My preference is to keep a ranking tied to its measurement process. The useful result here is that external tooling receives a less incomplete description of Nixpkgs. That helps someone evaluating the collection understand its breadth without requiring an unsupported claim about universal package availability or quality.
Channel advancement completes the observation
The community report explicitly mentions the channel advancing past the merged change. A source patch does not affect a downstream inventory until the exported data includes it and the consumer imports that data. The sequence explains the delay between correcting the repository's indexing configuration and observing its effect on the comparison. A comparison captured before that sequence completes can therefore understate the same repository's contents without any package definitions having been removed in the meantime.
December's milestone consequently records two kinds of work. Package maintainers had already populated the subsets, and the export change allowed those definitions to participate in the reported inventory. The immediate technical result is a wider, explicitly configured traversal with alias exclusion retained. That is enough to explain the observed ranking change without attributing all newly visible packages to work performed on the day the graph changed.