# Reverse dependencies of a package?

**URL:** <https://discourse.julialang.org/t/reverse-dependencies-of-a-package/9774>\
**Category:** General Usage\
**Tags:** package\
**Created:** [March 17, 2018, 4:31pm UTC](https://discourse.julialang.org/t/reverse-dependencies-of-a-package/9774 "2018-03-17T16:31:33Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![dmbates](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmbates/32/44_2.png) [@dmbates](https://discourse.julialang.org/u/dmbates)\
**Post date:** [March 17, 2018, 4:31pm UTC](https://discourse.julialang.org/t/reverse-dependencies-of-a-package/9774/1 "2018-03-17T16:31:33Z")

</div>

Are there existing tools for evaluating the reverse dependencies of a package? That is, for determining the packages that depend directly or indirectly on a particular package?

It occurred to me that, if not, this might be an occasion for me to learn a bit more about the Registries used with `Pkg3`. How would I begin exploring the TOML capabilities if I decided to try to parse a Registry?

---

<div class="post-metadata">

**Author:** ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)\
**Post date:** [March 17, 2018, 4:43pm UTC](https://discourse.julialang.org/t/reverse-dependencies-of-a-package/9774/2 "2018-03-17T16:43:17Z")

</div>

`Pkg.dependents` will give you the direct dependencies at least. Shouldn’t be hard to call it recursively if needed.

---

<div class="post-metadata">

**Author:** ![dmbates](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmbates/32/44_2.png) [@dmbates](https://discourse.julialang.org/u/dmbates)\
**Post date:** [March 17, 2018, 6:31pm UTC](https://discourse.julialang.org/t/reverse-dependencies-of-a-package/9774/3 "2018-03-17T18:31:44Z")

</div>

Thanks. It seems that I should have done a bit more research before asking the question.😬

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [March 17, 2018, 6:58pm UTC](https://discourse.julialang.org/t/reverse-dependencies-of-a-package/9774/4 "2018-03-17T18:58:17Z")

</div>

[https://juliaobserver.com](https://juliaobserver.com) will also give you this information.

---

<div class="post-metadata">

**Author:** ![goretkin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goretkin/32/167_2.png) [@goretkin](https://discourse.julialang.org/u/goretkin)\
**Post date:** [June 18, 2019, 11:34pm UTC](https://discourse.julialang.org/t/reverse-dependencies-of-a-package/9774/5 "2019-06-18T23:34:43Z")

</div>

This showed up in my Google search today. I don’t think the answers here still work, so I feel compelled to post, with apology, a kludge that does work. Perhaps someone will also post a more elegant solution which makes use of the dependency graph that I believe `Pkg` maintains in the first place.

```julia
import Pkg
ctx = Pkg.Types.Context()

latest_version(ctx, uuid) = maximum(keys(Pkg.Operations.load_versions(Pkg.Types.registered_paths(ctx.env, uuid)[])))

function latest_pkgspec(ctx, name)
  uuid = Pkg.Types.registered_uuid(ctx.env, name)
  Pkg.Types.PackageSpec(name, uuid, latest_version(ctx, uuid))
end

latest_deps(pkg_name) = Pkg.Operations.load_deps(ctx, latest_pkgspec(ctx, pkg_name))
latest_deps("Plots") # trigger populating of ctx.env

function reverse_deps(ctx, pkg_name_query)
  all_names = map(
    x->if length(x) == 1; x[]; else; nothing; end,
    values(ctx.env.names))
  all_names = filter(!isnothing, all_names)
  [pkg_name for pkg_name in all_names if pkg_name_query in keys(latest_deps(pkg_name))]
end

reverse_deps(ctx, "BinDeps")

```

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [February 19, 2020, 9:42am UTC](https://discourse.julialang.org/t/reverse-dependencies-of-a-package/9774/6 "2020-02-19T09:42:42Z")

</div>

Thanks for this snippet. Just a small note — in julia 1.4 I had to adjust this to use `ctx` rather than `ctx.env`.

---

<div class="post-metadata">

**Author:** ![ihnorton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihnorton/32/26_2.png) [@ihnorton](https://discourse.julialang.org/u/ihnorton)\
**Post date:** [March 9, 2021, 4:30am UTC](https://discourse.julialang.org/t/reverse-dependencies-of-a-package/9774/7 "2021-03-09T04:30:36Z")

</div>

Updated to run w/ 1.5/1.6 below. I say _to run_ because the output is wrong. `Pkg.Operations.load_all_deps` does not seem to be the correct function to get all dependencies for a package (assuming that’s what `Pkg.Operations.load_deps` did - it no longer exists). Rather, I believe `load_all_deps` returns all installed packages in the current environment.

```julia
julia> length(latest_deps("Revise"))
83

```

```julia
grep "\[\[" ~/.julia/environments/v1.6/Manifest.toml | wc -l
      83

```

Is there a function to return all dependencies based on a given package name or spec, ideally even if it is not installed?

* * *

```julia
import Pkg
ctx = Pkg.Types.Context()

latest_version(ctx, uuid) = maximum(keys(Pkg.Operations.load_versions(ctx, Pkg.Types.registered_paths(ctx, uuid)[])))

function latest_pkgspec(ctx, name)
  uuid = Pkg.Types.registered_uuid(ctx, name)
  Pkg.Types.PackageSpec(name, uuid, latest_version(ctx, uuid))
end

latest_deps(pkg_name) = map(x->x.name, Pkg.Operations.load_all_deps(ctx, [latest_pkgspec(ctx, pkg_name)]))
latest_deps("Plots") # trigger populating of ctx.env

function reverse_deps(ctx, pkg_name_query)
  all_names = map(
    x->if length(x) == 1; x[]; else; nothing; end,
    values(ctx.env.names))
  all_names = filter(!isnothing, all_names)
  [pkg_name for pkg_name in all_names if pkg_name_query in latest_deps(pkg_name)]
end

```

---

<div class="post-metadata">

**Author:** ![evetion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evetion/32/22679_2.png) [@evetion](https://discourse.julialang.org/u/evetion)\
**Post date:** [September 19, 2023, 11:39am UTC](https://discourse.julialang.org/t/reverse-dependencies-of-a-package/9774/8 "2023-09-19T11:39:37Z")

</div>

For anyone who found this topic through Google you can now (1.9) do

```julia
help?> Pkg.dependencies
  Pkg.dependencies()::Dict{UUID, PackageInfo}

  This feature is considered experimental.

  Query the dependency graph of the active project. The result is a Dict that maps a package UUID to a PackageInfo struct representing the dependency (a package).

  PackageInfo fields
  ≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡

  Field Description
  –––––––––––––––––––– –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
  name The name of the package
  version The version of the package (this is Nothing for stdlibs)
  tree_hash A file hash of the package directory tree
  is_direct_dep The package is a direct dependency
  is_pinned Whether a package is pinned
  is_tracking_path Whether a package is tracking a path
  is_tracking_repo Whether a package is tracking a repository
  is_tracking_registry Whether a package is being tracked by registry i.e. not by path nor by repository
  git_revision The git revision when tracking by repository
  git_source The git source when tracking by repository
  source The directory containing the source code for that package
  dependencies The dependencies of that package as a vector of UUIDs

```

---

<div class="post-metadata">

**Author:** ![Sevi](https://avatars.discourse-cdn.com/v4/letter/s/c67d28/32.png) [@Sevi](https://discourse.julialang.org/u/Sevi)\
**Post date:** [September 19, 2023, 1:13pm UTC](https://discourse.julialang.org/t/reverse-dependencies-of-a-package/9774/9 "2023-09-19T13:13:38Z")

</div>

Wait, doesn’t this just give the dependencies of the currently active project? If I understood the question correctly, it’s about finding the packages that depend on a given package. So, e.g. finding all the packages that use `Plots` or something like that.

---

<div class="post-metadata">

**Author:** ![evetion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evetion/32/22679_2.png) [@evetion](https://discourse.julialang.org/u/evetion)\
**Post date:** [September 20, 2023, 9:26am UTC](https://discourse.julialang.org/t/reverse-dependencies-of-a-package/9774/10 "2023-09-20T09:26:20Z")

</div>

Ah, yeah I misread.

This might do the trick for direct deps:

```julia
import Pkg
ctx = Pkg.Types.Context();

function reverse_deps(name)
    nuuid = Pkg.Types.registered_uuid(ctx.registries, name)
    dd = Dict{String,Base.UUID}()
    isnothing(nuuid) && "$name not known"
    for reg in Pkg.Registry.reachable_registries()
        for (uuid, regpkg) in reg
            pkg = Pkg.Registry.registry_info(regpkg)
            deps = reduce(merge, values(pkg.deps), init=Dict{String,Base.UUID}())
            x = get(deps, name, nothing)
            if !isnothing(x) && x == nuuid
                dd[regpkg.name] = uuid
            end

        end
    end
    dd
end

julia> reverse_deps("Plots")
Dict{String, Base.UUID} with 386 entries:
  "Kinetic" => UUID("82403725-3cee-4f7c-b214-1ce71af4a797")
  "SchumakerSpline" => UUID("65e68595-3a03-5ff5-a6a2-f05fa774f32e")
  "PicoQuant" => UUID("2db47837-5a65-4a20-8d0f-8ec2491baa53")
  "CellularPotts" => UUID("11b7dee7-cd95-48a5-a457-717aae94d0bd")
  "StockFlow" => UUID("58c4a0e8-2944-4d18-9fa2-e17726aee9e5")
  "Dyn3d" => UUID("d8047ffa-7f43-11e9-2204-adfbb6974ec5")
  "AirfoilGmsh" => UUID("e68ec710-8e48-43c5-af1a-c38c4248fd7b")
  "FlightGNC" => UUID("f141b7d0-6781-47a7-9266-a0707263841d")
  "AgentsPlots" => UUID("7820620d-95fb-4739-93b3-b0a14dd83f9a")
  "ItsLive" => UUID("774cd0c4-ba78-41e4-92fb-f5f90e3791d1")
  "BifurcationKit" => UUID("0f109fa4-8a5d-4b75-95aa-f515264e7665")
  "Population" => UUID("11b83ad2-e65e-47ba-870b-1ff818f3e30a")
  "LaplaceRedux" => UUID("c52c1a26-f7c5-402b-80be-ba1e638ad478")
  "ScenTreesMakie" => UUID("9bd120df-771c-42ec-88b3-c561e7179d1b")
  "AbstractPDEInterfaces" => UUID("db474457-f03d-4fd7-b196-5f323c96c803")
  "SemanticModels" => UUID("f5ac2a72-33c7-5caf-b863-f02fefdcf428")
  "VisClaw" => UUID("d5c85fe6-8620-4d3a-96f0-ac478d4f5d38")
  "AtariAlgos" => UUID("faabce77-3242-5060-abab-4a4767a0df42")
  "Smg2s" => UUID("36e52ba8-0d61-4da2-bc57-6d85c7a279e7")
  "FundamentalsNumericalComputation" => UUID("e48b7b93-d2a8-4750-aba7-f743ccd5256c")
  "Soss" => UUID("8ce77f84-9b61-11e8-39ff-d17a774bf41c")
  "DFTK" => UUID("acf6eb54-70d9-11e9-0013-234b7a5f5337")
  "CycleSolver" => UUID("3b43121a-1122-4a83-b2b6-7ec1eb6161aa")
  "CausalForest" => UUID("31bdf679-24a7-499a-9be9-b214c66174ea")
  "LineIntegralConvolution" => UUID("954431ae-a746-4b0b-bf75-a8381ca95b21")
  "TreesHeaps" => UUID("11f3e0e9-035a-4796-9f15-e39fd2303e8e")
  "Huginn" => UUID("9cb796e9-d0ea-421b-b37d-eb97bc1add55")
  "AlgebraicDynamics" => UUID("5fd6ff03-a254-427e-8840-ba658f502e32")
  "PosteriorPlots" => UUID("196f2941-2d58-45ba-9f13-43a2532b2fa8")
  "Bioinformatics" => UUID("c429c406-9079-5a14-8339-dedc8835de90")
  "SSMPlots" => UUID("b9734e3f-1fb5-4b0f-895a-a4ed7ba034cc")
  "VoronoiFVM" => UUID("82b139dc-5afc-11e9-35da-9b9bdfd336f3")
  "LazySets" => UUID("b4f0291d-fe17-52bc-9479-3d1a343d9043")
  "IndirectTrajOpt" => UUID("99e47ffd-a99c-4d17-8b51-d4481b168213")
  "Skyler" => UUID("804faec8-72f5-11ea-307d-47b816e9b733")
  "MOSLab" => UUID("646a8480-3455-4dcb-93e7-a10dc646a0af")
  "Trixi2Img" => UUID("821991e7-028e-4e54-884c-f74f8833bc95")
  "MonotoneSplines" => UUID("92812004-5f8d-4354-96af-0c8b7c0637d0")
  "BoseWormPIMC" => UUID("bd945c55-3bff-4c7d-84e7-fefb69b5105e")
  "ConScape" => UUID("2ba2d6f2-f651-5162-bda8-601e45ce5244")
  "Clines" => UUID("b03ef683-e087-4e84-9649-40693305c655")
  "AlphaZero" => UUID("8ed9eb0b-7496-408d-8c8b-2119aeea02cd")
  "Solaris" => UUID("c31bc6c7-79d6-424e-a85f-5b42ee086500")
  "KnetMetrics" => UUID("33081891-0f5e-47f5-81c7-76d5d1fed490")
  "Bingomatic" => UUID("5d0f211d-823e-4d77-a844-586f1e6d1e5a")
  "ConservationLawsParticles" => UUID("dbb53eb6-f4e4-11e9-1aca-071dd871ed0a")
  "RvSpectMLPlots" => UUID("6ad363e8-653f-4efd-a04b-f033e69a984c")
  "ClimaCore" => UUID("d414da3d-4745-48bb-8d80-42e94e092884")
  "TightBindingToolkit" => UUID("2233325a-6eb3-486f-aff0-670e0939fa7e")
  "LassoPlot" => UUID("21d151f5-1f6d-55ec-8524-1c9aee35b0a4")
  "FixedPointToolkit" => UUID("081f7a28-ac82-48c1-a10e-fa8b3349a52a")
  "BifurcationInference" => UUID("7fe238d6-d31e-4646-aa16-9d8429fd6da8")
  ⋮ => ⋮

```

---

<div class="post-metadata">

**Author:** ![DanDeepPhase](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dandeepphase/32/24076_2.png) [@DanDeepPhase](https://discourse.julialang.org/u/DanDeepPhase)\
**Post date:** [January 10, 2025, 10:58pm UTC](https://discourse.julialang.org/t/reverse-dependencies-of-a-package/9774/11 "2025-01-10T22:58:36Z")

</div>

Since this 7 year old thread was still the first relevant one in my google search, I’ll tack on an alternate take: A simpler solution for a simpler question.

When I’m looking at “reverse dependencies” it is for a single package, not for all the packages. So rather than “For every package, what packages depend on it?”, this answers “Why is PackageXYZ installed?”. I think this is the same scope as the original question.

for example, i was trying to figure out which Package was using IntervalSets  
From the Pkg repl:

```julia
 pkg> why IntervalSets
  DimensionalData → IntervalSets
  Images → ImageAxes → AxisArrays → IntervalSets
  Images → ImageMetadata → AxisArrays → IntervalSets
  Images → ImageMetadata → ImageAxes → AxisArrays → IntervalSets
  Images → IntegralArrays → IntervalSets
  Makie → ImageIO → Netpbm → ImageMetadata → AxisArrays → IntervalSets
... 

```

`why` lists the dependency chain from the packages in the environment to the package in question.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 10, 2025, 11:31pm UTC](https://discourse.julialang.org/t/reverse-dependencies-of-a-package/9774/12 "2025-01-10T23:31:49Z")

</div>

> [@anon94023334](#):
>
> [https://juliaobserver.com](https://juliaobserver.com) will also give you this information.

That site is defunct, but you can use [JuliaHub](https://juliahub.com/ui/Packages)
