[{"data":1,"prerenderedAt":1237},["ShallowReactive",2],{"NoscriptNav_XrRK2e2e8meJ0jKVGkb5ULGQDVi3UiFQ9nupAr7Yns":3,"\u002Freports\u002Fcategorizing-package-manager-clients":8},["Island",4],{"key":5,"result":6},"NoscriptNav_XrRK2e2e8meJ0jKVGkb5ULGQDVi3UiFQ9nupAr7Yns",{"head":7},{},{"id":9,"title":10,"authors":11,"body":13,"canonicalUrl":1223,"canonicalWebsiteName":1224,"category":1225,"date":1226,"description":1227,"extension":1228,"featured":1229,"fullWidthLayout":1229,"image":1230,"imageAlt":1230,"location":1230,"meta":1231,"metaImage":1230,"navigation":1232,"path":1233,"seo":1234,"stem":1235,"venue":1230,"venueUrl":1230,"__hash__":1236},"reports\u002Freports\u002Fcategorizing-package-manager-clients.md","Categorizing Package Manager Clients",[12],"andrew",{"type":14,"value":15,"toc":1215},"minimark",[16,33,36,41,50,67,176,182,201,207,220,230,246,252,273,279,331,341,349,355,383,389,394,400,408,412,415,421,483,489,501,507,553,559,565,569,572,578,672,678,712,718,737,741,744,749,761,766,780,785,799,804,836,841,849,854,866],[17,18,19,20,25,26,32],"p",{},"This is the companion to ",[21,22,24],"a",{"href":23},"\u002Freports\u002Fcategorizing-package-registries","Categorizing Package Registries",", focusing on the client side: how package managers resolve dependencies, track versions, run build code, and declare dependencies. The data is also available as ",[21,27,31],{"href":28,"rel":29},"https:\u002F\u002Fgithub.com\u002Fandrew\u002Fnesbitt.io\u002Fblob\u002Fmaster\u002Fdata\u002Fpackage-manager-clients.csv",[30],"nofollow","CSV",". There are gaps; contributions welcome.",[17,34,35],{},"Each package manager combines these choices differently. Cargo uses backtracking resolution, generates lockfiles, allows build hooks via build.rs, and uses TOML manifests. Go uses minimal version selection, achieves reproducibility without lockfiles, forbids hooks entirely, and embeds dependencies in go.mod. npm uses deduplication with nesting, generates lockfiles, allows postinstall hooks, and uses JSON. The particular combination shapes the developer experience more than any single choice.",[37,38,40],"h2",{"id":39},"resolution-algorithms","Resolution algorithms",[17,42,43,44,49],{},"How does the package manager decide which versions to install? The ",[21,45,48],{"href":46,"rel":47},"https:\u002F\u002Fgithub.com\u002Fecosyste-ms\u002Fpackage-manager-resolvers",[30],"ecosyste.ms resolver documentation"," covers the major algorithm families.",[17,51,52,60,61,66],{},[21,53,56],{"href":54,"rel":55},"https:\u002F\u002Fresearch.swtch.com\u002Fversion-sat",[30],[57,58,59],"strong",{},"SAT solving"," treats resolution as a satisfiability problem. Can find solutions when they exist and prove when they don't, but computationally expensive. ",[21,62,65],{"href":63,"rel":64},"https:\u002F\u002Fnex3.medium.com\u002Fpubgrub-2fb6470504f",[30],"PubGrub"," is a variant that produces better error messages by tracking why versions were excluded.",[68,69,70,74,77,91,100,111,122,131,140,149,158,167],"ul",{},[71,72,73],"li",{},"Composer",[71,75,76],{},"DNF",[71,78,79,80],{},"Conda\u002FMamba",[81,82,83],"sup",{},[21,84,90],{"href":85,"ariaDescribedBy":86,"dataFootnoteRef":88,"id":89},"#user-content-fn-libsolv",[87],"footnote-label","","user-content-fnref-libsolv","1",[71,92,93,94],{},"Zypper",[81,95,96],{},[21,97,90],{"href":85,"ariaDescribedBy":98,"dataFootnoteRef":88,"id":99},[87],"user-content-fnref-libsolv-2",[71,101,102,103],{},"opam",[81,104,105],{},[21,106,110],{"href":107,"ariaDescribedBy":108,"dataFootnoteRef":88,"id":109},"#user-content-fn-opam-cudf",[87],"user-content-fnref-opam-cudf","2",[71,112,113,114],{},"pub",[81,115,116],{},[21,117,121],{"href":118,"ariaDescribedBy":119,"dataFootnoteRef":88,"id":120},"#user-content-fn-pubgrub",[87],"user-content-fnref-pubgrub","3",[71,123,124,125],{},"Poetry",[81,126,127],{},[21,128,121],{"href":118,"ariaDescribedBy":129,"dataFootnoteRef":88,"id":130},[87],"user-content-fnref-pubgrub-2",[71,132,133,134],{},"uv",[81,135,136],{},[21,137,121],{"href":118,"ariaDescribedBy":138,"dataFootnoteRef":88,"id":139},[87],"user-content-fnref-pubgrub-3",[71,141,142,143],{},"pdm",[81,144,145],{},[21,146,121],{"href":118,"ariaDescribedBy":147,"dataFootnoteRef":88,"id":148},[87],"user-content-fnref-pubgrub-4",[71,150,151,152],{},"Swift Package Manager",[81,153,154],{},[21,155,121],{"href":118,"ariaDescribedBy":156,"dataFootnoteRef":88,"id":157},[87],"user-content-fnref-pubgrub-5",[71,159,160,161],{},"Hex",[81,162,163],{},[21,164,121],{"href":118,"ariaDescribedBy":165,"dataFootnoteRef":88,"id":166},[87],"user-content-fnref-pubgrub-6",[71,168,169,170],{},"Bundler",[81,171,172],{},[21,173,121],{"href":118,"ariaDescribedBy":174,"dataFootnoteRef":88,"id":175},[87],"user-content-fnref-pubgrub-7",[17,177,178,181],{},[57,179,180],{},"Backtracking"," tries versions in order and backs up when conflicts arise.",[68,183,184,187,190],{},[71,185,186],{},"pip",[71,188,189],{},"Cargo",[71,191,192,193],{},"Cabal",[81,194,195],{},[21,196,200],{"href":197,"ariaDescribedBy":198,"dataFootnoteRef":88,"id":199},"#user-content-fn-cabal-solver",[87],"user-content-fnref-cabal-solver","4",[17,202,203,206],{},[57,204,205],{},"ASP solving"," uses answer set programming for complex constraint solving.",[68,208,209],{},[71,210,211,212],{},"Spack",[81,213,214],{},[21,215,219],{"href":216,"ariaDescribedBy":217,"dataFootnoteRef":88,"id":218},"#user-content-fn-spack-clingo",[87],"user-content-fnref-spack-clingo","5",[17,221,222,229],{},[21,223,226],{"href":224,"rel":225},"https:\u002F\u002Fresearch.swtch.com\u002Fvgo-mvs",[30],[57,227,228],{},"Minimal version selection"," picks the oldest version that satisfies constraints.",[68,231,232,235],{},[71,233,234],{},"Go modules",[71,236,237,238],{},"vcpkg",[81,239,240],{},[21,241,245],{"href":242,"ariaDescribedBy":243,"dataFootnoteRef":88,"id":244},"#user-content-fn-vcpkg-mvs",[87],"user-content-fnref-vcpkg-mvs","6",[17,247,248,251],{},[57,249,250],{},"Deduplication with nesting"," installs multiple versions when packages need incompatible versions.",[68,253,254,257,260,263],{},[71,255,256],{},"npm",[71,258,259],{},"Yarn",[71,261,262],{},"pnpm",[71,264,189,265],{},[81,266,267],{},[21,268,272],{"href":269,"ariaDescribedBy":270,"dataFootnoteRef":88,"id":271},"#user-content-fn-cargo-semver-compat",[87],"user-content-fnref-cargo-semver-compat","7",[17,274,275,278],{},[57,276,277],{},"Version mediation"," lets build systems pick winners using different strategies.",[68,280,281,292,303,314,317,328],{},[71,282,283,284],{},"Maven",[81,285,286],{},[21,287,291],{"href":288,"ariaDescribedBy":289,"dataFootnoteRef":88,"id":290},"#user-content-fn-maven-nearest",[87],"user-content-fnref-maven-nearest","8",[71,293,294,295],{},"Gradle",[81,296,297],{},[21,298,302],{"href":299,"ariaDescribedBy":300,"dataFootnoteRef":88,"id":301},"#user-content-fn-gradle-highest",[87],"user-content-fnref-gradle-highest","9",[71,304,305,306],{},"NuGet",[81,307,308],{},[21,309,313],{"href":310,"ariaDescribedBy":311,"dataFootnoteRef":88,"id":312},"#user-content-fn-nuget-lowest",[87],"user-content-fnref-nuget-lowest","10",[71,315,316],{},"sbt",[71,318,319,320],{},"Clojars",[81,321,322],{},[21,323,327],{"href":324,"ariaDescribedBy":325,"dataFootnoteRef":88,"id":326},"#user-content-fn-clojars-maven",[87],"user-content-fnref-clojars-maven","11",[71,329,330],{},"Ivy",[17,332,333,340],{},[21,334,337],{"href":335,"rel":336},"https:\u002F\u002Fgithub.com\u002FCocoaPods\u002FMolinillo",[30],[57,338,339],{},"Molinillo"," is a backtracking solver with heuristics tuned for Ruby's ecosystem.",[68,342,343,346],{},[71,344,345],{},"RubyGems",[71,347,348],{},"CocoaPods",[17,350,351,354],{},[57,352,353],{},"System package resolution"," handles system-level constraints like file conflicts and provides\u002Frequires relationships.",[68,356,357,368,371,374,377,380],{},[71,358,359,360],{},"apt",[81,361,362],{},[21,363,367],{"href":364,"ariaDescribedBy":365,"dataFootnoteRef":88,"id":366},"#user-content-fn-apt-scoring",[87],"user-content-fnref-apt-scoring","12",[71,369,370],{},"pacman",[71,372,373],{},"apk",[71,375,376],{},"Portage",[71,378,379],{},"FreeBSD ports",[71,381,382],{},"pkgsrc",[17,384,385,388],{},[57,386,387],{},"Single version per formula"," with topological sort for dependency ordering.",[68,390,391],{},[71,392,393],{},"Homebrew",[17,395,396,399],{},[57,397,398],{},"Explicit dependencies"," with no version resolution needed.",[68,401,402,405],{},[71,403,404],{},"Nix",[71,406,407],{},"Guix",[37,409,411],{"id":410},"lockfiles-and-reproducibility","Lockfiles and reproducibility",[17,413,414],{},"Can you reproduce the same install later?",[17,416,417,420],{},[57,418,419],{},"Generates lockfiles"," to record exact versions resolved. Committed to version control.",[68,422,423,425,427,429,431,433,435,437,439,441,444,446,448,451,461,464,466,468,470,473,476,479,481],{},[71,424,169],{},[71,426,256],{},[71,428,259],{},[71,430,262],{},[71,432,189],{},[71,434,124],{},[71,436,133],{},[71,438,142],{},[71,440,73],{},[71,442,443],{},"Mix",[71,445,113],{},[71,447,151],{},[71,449,450],{},"Elm",[71,452,192,453],{},[81,454,455],{},[21,456,460],{"href":457,"ariaDescribedBy":458,"dataFootnoteRef":88,"id":459},"#user-content-fn-cabal-freeze",[87],"user-content-fnref-cabal-freeze","13",[71,462,463],{},"Stack",[71,465,211],{},[71,467,393],{},[71,469,305],{},[71,471,472],{},"Julia",[71,474,475],{},"Conan",[71,477,478],{},"dub",[71,480,348],{},[71,482,102],{},[17,484,485,488],{},[57,486,487],{},"Deterministic resolution"," through algorithms that produce stable results without needing a lockfile to pin versions.",[68,490,491],{},[71,492,234,493],{},[81,494,495],{},[21,496,500],{"href":497,"ariaDescribedBy":498,"dataFootnoteRef":88,"id":499},"#user-content-fn-go-sum",[87],"user-content-fnref-go-sum","14",[17,502,503,506],{},[57,504,505],{},"No native lockfile"," means resolution happens fresh each time, or build systems handle pinning.",[68,508,509,519,521,523,525,528,539,542],{},[71,510,186,511],{},[81,512,513],{},[21,514,518],{"href":515,"ariaDescribedBy":516,"dataFootnoteRef":88,"id":517},"#user-content-fn-pip-lockfiles",[87],"user-content-fnref-pip-lockfiles","15",[71,520,283],{},[71,522,294],{},[71,524,359],{},[71,526,527],{},"CRAN",[71,529,530,531],{},"Hackage",[81,532,533],{},[21,534,538],{"href":535,"ariaDescribedBy":536,"dataFootnoteRef":88,"id":537},"#user-content-fn-hackage-freeze",[87],"user-content-fnref-hackage-freeze","16",[71,540,541],{},"CPAN",[71,543,544,545],{},"Conda",[81,546,547],{},[21,548,552],{"href":549,"ariaDescribedBy":550,"dataFootnoteRef":88,"id":551},"#user-content-fn-conda-lock",[87],"user-content-fnref-conda-lock","17",[17,554,555,558],{},[57,556,557],{},"Content-addressed"," packages are identified by input hash. Reproducibility without traditional lockfiles.",[68,560,561,563],{},[71,562,404],{},[71,564,407],{},[37,566,568],{"id":567},"build-hooks","Build hooks",[17,570,571],{},"Can packages run code during installation?",[17,573,574,577],{},[57,575,576],{},"Hooks allowed"," let packages execute scripts during install, build, or publish.",[68,579,580,590,592,602,612,622,632,634,644,646,648,658,669],{},[71,581,256,582],{},[81,583,584],{},[21,585,589],{"href":586,"ariaDescribedBy":587,"dataFootnoteRef":88,"id":588},"#user-content-fn-npm-postinstall",[87],"user-content-fnref-npm-postinstall","18",[71,591,259],{},[71,593,186,594],{},[81,595,596],{},[21,597,601],{"href":598,"ariaDescribedBy":599,"dataFootnoteRef":88,"id":600},"#user-content-fn-pip-setuppy",[87],"user-content-fnref-pip-setuppy","19",[71,603,73,604],{},[81,605,606],{},[21,607,611],{"href":608,"ariaDescribedBy":609,"dataFootnoteRef":88,"id":610},"#user-content-fn-composer-scripts",[87],"user-content-fnref-composer-scripts","20",[71,613,345,614],{},[81,615,616],{},[21,617,621],{"href":618,"ariaDescribedBy":619,"dataFootnoteRef":88,"id":620},"#user-content-fn-rubygems-extensions",[87],"user-content-fnref-rubygems-extensions","21",[71,623,283,624],{},[81,625,626],{},[21,627,631],{"href":628,"ariaDescribedBy":629,"dataFootnoteRef":88,"id":630},"#user-content-fn-maven-plugins",[87],"user-content-fnref-maven-plugins","22",[71,633,294],{},[71,635,189,636],{},[81,637,638],{},[21,639,643],{"href":640,"ariaDescribedBy":641,"dataFootnoteRef":88,"id":642},"#user-content-fn-cargo-buildrs",[87],"user-content-fnref-cargo-buildrs","23",[71,645,348],{},[71,647,393],{},[71,649,404,650],{},[81,651,652],{},[21,653,657],{"href":654,"ariaDescribedBy":655,"dataFootnoteRef":88,"id":656},"#user-content-fn-nix-sandboxed",[87],"user-content-fnref-nix-sandboxed","24",[71,659,660,661],{},"apt\u002Fdpkg",[81,662,663],{},[21,664,668],{"href":665,"ariaDescribedBy":666,"dataFootnoteRef":88,"id":667},"#user-content-fn-system-postinst",[87],"user-content-fnref-system-postinst","25",[71,670,671],{},"RPM\u002FDNF",[17,673,674,677],{},[57,675,676],{},"Hooks restricted"," allow some build-time execution with limitations.",[68,679,680,690,701],{},[71,681,262,682],{},[81,683,684],{},[21,685,689],{"href":686,"ariaDescribedBy":687,"dataFootnoteRef":88,"id":688},"#user-content-fn-pnpm-disabled",[87],"user-content-fnref-pnpm-disabled","26",[71,691,692,693],{},"Bun",[81,694,695],{},[21,696,700],{"href":697,"ariaDescribedBy":698,"dataFootnoteRef":88,"id":699},"#user-content-fn-bun-disabled",[87],"user-content-fnref-bun-disabled","27",[71,702,703,704],{},"Deno",[81,705,706],{},[21,707,711],{"href":708,"ariaDescribedBy":709,"dataFootnoteRef":88,"id":710},"#user-content-fn-deno-permissions",[87],"user-content-fnref-deno-permissions","28",[17,713,714,717],{},[57,715,716],{},"No hooks"," by design.",[68,719,720,723,725,727],{},[71,721,722],{},"Go",[71,724,450],{},[71,726,151],{},[71,728,186,729],{},[81,730,731],{},[21,732,736],{"href":733,"ariaDescribedBy":734,"dataFootnoteRef":88,"id":735},"#user-content-fn-pip-wheels",[87],"user-content-fnref-pip-wheels","29",[37,738,740],{"id":739},"manifest-format","Manifest format",[17,742,743],{},"How are dependencies declared?",[17,745,746],{},[57,747,748],{},"TOML",[68,750,751,753,755,757,759],{},[71,752,189],{},[71,754,124],{},[71,756,133],{},[71,758,472],{},[71,760,142],{},[17,762,763],{},[57,764,765],{},"JSON",[68,767,768,770,772,774,776,778],{},[71,769,256],{},[71,771,73],{},[71,773,703],{},[71,775,450],{},[71,777,478],{},[71,779,237],{},[17,781,782],{},[57,783,784],{},"YAML",[68,786,787,789,791,794,797],{},[71,788,544],{},[71,790,113],{},[71,792,793],{},"GitHub Actions",[71,795,796],{},"Helm",[71,798,262],{},[17,800,801],{},[57,802,803],{},"Host language",[68,805,806,809,812,815,818,821,824,827,830,833],{},[71,807,808],{},"Bundler (Ruby)",[71,810,811],{},"CocoaPods (Ruby)",[71,813,814],{},"Gradle (Groovy\u002FKotlin)",[71,816,817],{},"Homebrew (Ruby)",[71,819,820],{},"Leiningen (Clojure)",[71,822,823],{},"Mix (Elixir)",[71,825,826],{},"Nix (nix)",[71,828,829],{},"Spack (Python)",[71,831,832],{},"Swift Package Manager (Swift)",[71,834,835],{},"sbt (Scala)",[17,837,838],{},[57,839,840],{},"XML",[68,842,843,845,847],{},[71,844,283],{},[71,846,305],{},[71,848,330],{},[17,850,851],{},[57,852,853],{},"Custom format",[68,855,856,858,860,862,864],{},[71,857,722],{},[71,859,192],{},[71,861,541],{},[71,863,527],{},[71,865,186],{},[867,868,871,876],"section",{"className":869,"dataFootnotes":88},[870],"footnotes",[37,872,875],{"className":873,"id":87},[874],"sr-only","Footnotes",[877,878,879,904,913,967,976,989,1003,1012,1021,1030,1039,1048,1057,1071,1080,1089,1098,1107,1116,1125,1134,1143,1152,1161,1170,1179,1188,1197,1206],"ol",{},[71,880,882,883,888,889,896,897],{"id":881},"user-content-fn-libsolv","Via ",[21,884,887],{"href":885,"rel":886},"https:\u002F\u002Fgithub.com\u002FopenSUSE\u002Flibsolv",[30],"libsolv",". ",[21,890,895],{"href":891,"ariaLabel":892,"className":893,"dataFootnoteBackref":88},"#user-content-fnref-libsolv","Back to reference 1",[894],"data-footnote-backref","↩"," ",[21,898,895,902],{"href":899,"ariaLabel":900,"className":901,"dataFootnoteBackref":88},"#user-content-fnref-libsolv-2","Back to reference 1-2",[894],[81,903,110],{},[71,905,907,908],{"id":906},"user-content-fn-opam-cudf","Uses external CUDF solvers. ",[21,909,895],{"href":910,"ariaLabel":911,"className":912,"dataFootnoteBackref":88},"#user-content-fnref-opam-cudf","Back to reference 2",[894],[71,914,916,917,888,920,896,925,896,932,896,939,896,946,896,953,896,960],{"id":915},"user-content-fn-pubgrub","Uses ",[21,918,65],{"href":63,"rel":919},[30],[21,921,895],{"href":922,"ariaLabel":923,"className":924,"dataFootnoteBackref":88},"#user-content-fnref-pubgrub","Back to reference 3",[894],[21,926,895,930],{"href":927,"ariaLabel":928,"className":929,"dataFootnoteBackref":88},"#user-content-fnref-pubgrub-2","Back to reference 3-2",[894],[81,931,110],{},[21,933,895,937],{"href":934,"ariaLabel":935,"className":936,"dataFootnoteBackref":88},"#user-content-fnref-pubgrub-3","Back to reference 3-3",[894],[81,938,121],{},[21,940,895,944],{"href":941,"ariaLabel":942,"className":943,"dataFootnoteBackref":88},"#user-content-fnref-pubgrub-4","Back to reference 3-4",[894],[81,945,200],{},[21,947,895,951],{"href":948,"ariaLabel":949,"className":950,"dataFootnoteBackref":88},"#user-content-fnref-pubgrub-5","Back to reference 3-5",[894],[81,952,219],{},[21,954,895,958],{"href":955,"ariaLabel":956,"className":957,"dataFootnoteBackref":88},"#user-content-fnref-pubgrub-6","Back to reference 3-6",[894],[81,959,245],{},[21,961,895,965],{"href":962,"ariaLabel":963,"className":964,"dataFootnoteBackref":88},"#user-content-fnref-pubgrub-7","Back to reference 3-7",[894],[81,966,272],{},[71,968,970,971],{"id":969},"user-content-fn-cabal-solver","Modular solver with backjumping. ",[21,972,895],{"href":973,"ariaLabel":974,"className":975,"dataFootnoteBackref":88},"#user-content-fnref-cabal-solver","Back to reference 4",[894],[71,977,882,979,888,984],{"id":978},"user-content-fn-spack-clingo",[21,980,983],{"href":981,"rel":982},"https:\u002F\u002Fpotassco.org\u002Fclingo\u002F",[30],"Clingo",[21,985,895],{"href":986,"ariaLabel":987,"className":988,"dataFootnoteBackref":88},"#user-content-fnref-spack-clingo","Back to reference 5",[894],[71,990,992,993,888,998],{"id":991},"user-content-fn-vcpkg-mvs","Microsoft explicitly documents vcpkg's ",[21,994,997],{"href":995,"rel":996},"https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fvcpkg\u002Fusers\u002Fversioning.concepts",[30],"minimal version selection algorithm",[21,999,895],{"href":1000,"ariaLabel":1001,"className":1002,"dataFootnoteBackref":88},"#user-content-fnref-vcpkg-mvs","Back to reference 6",[894],[71,1004,1006,1007],{"id":1005},"user-content-fn-cargo-semver-compat","Limited to one version per semver-compatible range (one per major version, or one per minor if pre-1.0). ",[21,1008,895],{"href":1009,"ariaLabel":1010,"className":1011,"dataFootnoteBackref":88},"#user-content-fnref-cargo-semver-compat","Back to reference 7",[894],[71,1013,1015,1016],{"id":1014},"user-content-fn-maven-nearest","Nearest definition wins. ",[21,1017,895],{"href":1018,"ariaLabel":1019,"className":1020,"dataFootnoteBackref":88},"#user-content-fnref-maven-nearest","Back to reference 8",[894],[71,1022,1024,1025],{"id":1023},"user-content-fn-gradle-highest","Highest version wins. ",[21,1026,895],{"href":1027,"ariaLabel":1028,"className":1029,"dataFootnoteBackref":88},"#user-content-fnref-gradle-highest","Back to reference 9",[894],[71,1031,1033,1034],{"id":1032},"user-content-fn-nuget-lowest","Lowest applicable version. ",[21,1035,895],{"href":1036,"ariaLabel":1037,"className":1038,"dataFootnoteBackref":88},"#user-content-fnref-nuget-lowest","Back to reference 10",[894],[71,1040,1042,1043],{"id":1041},"user-content-fn-clojars-maven","Clojars uses Maven's resolution algorithm since it's a Maven-compatible repository. ",[21,1044,895],{"href":1045,"ariaLabel":1046,"className":1047,"dataFootnoteBackref":88},"#user-content-fnref-clojars-maven","Back to reference 11",[894],[71,1049,1051,1052],{"id":1050},"user-content-fn-apt-scoring","Scoring with immediate resolution. ",[21,1053,895],{"href":1054,"ariaLabel":1055,"className":1056,"dataFootnoteBackref":88},"#user-content-fnref-apt-scoring","Back to reference 12",[894],[71,1058,1060,1061,1065,1066],{"id":1059},"user-content-fn-cabal-freeze","The ",[1062,1063,1064],"code",{},"cabal freeze"," command generates a freeze file pinning versions. ",[21,1067,895],{"href":1068,"ariaLabel":1069,"className":1070,"dataFootnoteBackref":88},"#user-content-fnref-cabal-freeze","Back to reference 13",[894],[71,1072,1074,1075],{"id":1073},"user-content-fn-go-sum","go.sum exists but contains checksums for verification, not version pins. MVS means the same go.mod always resolves to the same versions. ",[21,1076,895],{"href":1077,"ariaLabel":1078,"className":1079,"dataFootnoteBackref":88},"#user-content-fnref-go-sum","Back to reference 14",[894],[71,1081,1083,1084],{"id":1082},"user-content-fn-pip-lockfiles","pip-tools, Poetry, and uv provide lockfile functionality for pip. ",[21,1085,895],{"href":1086,"ariaLabel":1087,"className":1088,"dataFootnoteBackref":88},"#user-content-fnref-pip-lockfiles","Back to reference 15",[894],[71,1090,1092,1093],{"id":1091},"user-content-fn-hackage-freeze","Cabal can generate freeze files, but Hackage itself doesn't require them. ",[21,1094,895],{"href":1095,"ariaLabel":1096,"className":1097,"dataFootnoteBackref":88},"#user-content-fnref-hackage-freeze","Back to reference 16",[894],[71,1099,1101,1102],{"id":1100},"user-content-fn-conda-lock","conda-lock is a separate tool that adds lockfile support. ",[21,1103,895],{"href":1104,"ariaLabel":1105,"className":1106,"dataFootnoteBackref":88},"#user-content-fnref-conda-lock","Back to reference 17",[894],[71,1108,1110,1111],{"id":1109},"user-content-fn-npm-postinstall","postinstall scripts run after package installation. ",[21,1112,895],{"href":1113,"ariaLabel":1114,"className":1115,"dataFootnoteBackref":88},"#user-content-fnref-npm-postinstall","Back to reference 18",[894],[71,1117,1119,1120],{"id":1118},"user-content-fn-pip-setuppy","Historically via setup.py; modern PEP 517 builds use wheel build backends, which still execute arbitrary code at build time. ",[21,1121,895],{"href":1122,"ariaLabel":1123,"className":1124,"dataFootnoteBackref":88},"#user-content-fnref-pip-setuppy","Back to reference 19",[894],[71,1126,1128,1129],{"id":1127},"user-content-fn-composer-scripts","Composer scripts can run at various lifecycle points. ",[21,1130,895],{"href":1131,"ariaLabel":1132,"className":1133,"dataFootnoteBackref":88},"#user-content-fnref-composer-scripts","Back to reference 20",[894],[71,1135,1137,1138],{"id":1136},"user-content-fn-rubygems-extensions","Native extensions compile C code during installation. ",[21,1139,895],{"href":1140,"ariaLabel":1141,"className":1142,"dataFootnoteBackref":88},"#user-content-fnref-rubygems-extensions","Back to reference 21",[894],[71,1144,1146,1147],{"id":1145},"user-content-fn-maven-plugins","Maven plugins execute during build phases. ",[21,1148,895],{"href":1149,"ariaLabel":1150,"className":1151,"dataFootnoteBackref":88},"#user-content-fnref-maven-plugins","Back to reference 22",[894],[71,1153,1155,1156],{"id":1154},"user-content-fn-cargo-buildrs","build.rs scripts run at compile time, typically for native code compilation. ",[21,1157,895],{"href":1158,"ariaLabel":1159,"className":1160,"dataFootnoteBackref":88},"#user-content-fnref-cargo-buildrs","Back to reference 23",[894],[71,1162,1164,1165],{"id":1163},"user-content-fn-nix-sandboxed","Build hooks run in a sandboxed environment. ",[21,1166,895],{"href":1167,"ariaLabel":1168,"className":1169,"dataFootnoteBackref":88},"#user-content-fnref-nix-sandboxed","Back to reference 24",[894],[71,1171,1173,1174],{"id":1172},"user-content-fn-system-postinst","System packages do have maintainer scripts that run as root, but those are part of the distribution's build pipeline, not arbitrary user-space package hooks. ",[21,1175,895],{"href":1176,"ariaLabel":1177,"className":1178,"dataFootnoteBackref":88},"#user-content-fnref-system-postinst","Back to reference 25",[894],[71,1180,1182,1183],{"id":1181},"user-content-fn-pnpm-disabled","Scripts are disabled by default; must be explicitly enabled. ",[21,1184,895],{"href":1185,"ariaLabel":1186,"className":1187,"dataFootnoteBackref":88},"#user-content-fnref-pnpm-disabled","Back to reference 26",[894],[71,1189,1191,1192],{"id":1190},"user-content-fn-bun-disabled","Lifecycle scripts are disabled by default. ",[21,1193,895],{"href":1194,"ariaLabel":1195,"className":1196,"dataFootnoteBackref":88},"#user-content-fnref-bun-disabled","Back to reference 27",[894],[71,1198,1200,1201],{"id":1199},"user-content-fn-deno-permissions","Requires explicit permission flags for network, file system, and subprocess access. ",[21,1202,895],{"href":1203,"ariaLabel":1204,"className":1205,"dataFootnoteBackref":88},"#user-content-fnref-deno-permissions","Back to reference 28",[894],[71,1207,1209,1210],{"id":1208},"user-content-fn-pip-wheels","Wheel format explicitly forbids install-time code execution; sdist still allows setup.py hooks. ",[21,1211,895],{"href":1212,"ariaLabel":1213,"className":1214,"dataFootnoteBackref":88},"#user-content-fnref-pip-wheels","Back to reference 29",[894],{"title":88,"searchDepth":1216,"depth":1216,"links":1217},2,[1218,1219,1220,1221,1222],{"id":39,"depth":1216,"text":40},{"id":410,"depth":1216,"text":411},{"id":567,"depth":1216,"text":568},{"id":739,"depth":1216,"text":740},{"id":87,"depth":1216,"text":875},"https:\u002F\u002Fnesbitt.io\u002F2025\u002F12\u002F29\u002Fcategorizing-package-manager-clients","nesbitt.io","package-management","2025-12-29","Sorting package manager clients by resolution algorithms, lockfile strategies, build hooks, and manifest formats.","md",false,null,{},true,"\u002Freports\u002Fcategorizing-package-manager-clients",{"title":10,"description":1227},"reports\u002Fcategorizing-package-manager-clients","axWdEMP0awvWmePaxl1QrFFu8Nub78pDnqZV9QcAuOg",1780596102973]