How to use Pkg.dependencies() instead of Pkg.installed()

Just take a look at the current implementation of Pkg.installed():

function installed()
    @warn "Pkg.installed() is deprecated"
    deps = dependencies()
    installs = Dict{String, VersionNumber}()
    for (uuid, dep) in deps
        dep.is_direct_dep || continue
        dep.version === nothing && continue
        installs[] = dep.version
    return installs

You just need to look at the field is_direct_dep :smile:.


Why do you need Pkg.installed()?

Oh. Great!!. Your answer is totally what I want!!

Sometimes, I want to check a certain package is installed or not in a Julia script for dependency management.

1 Like

For such cases Requires is also super helpful by the way:


So, what is the best way to check if a package is already installed ? I often want to say “If package xxx is not present, add it”.

In my system:

haskey(Pkg.installed(), "StatsPlots") # true
haskey(Pkg.dependencies(), "StatsPlots") #false
1 Like

Use the UUID of StatsPlots as the key instead.

1 Like

Thank you, I found it:

haskey(Pkg.installed(), "StatsPlots") # true
haskey(Pkg.dependencies(), Base.UUID("f3b207a7-027a-5e70-b257-86293d7955fd")) # true

However on a usability prospective it is terrible, it is a regression compared to the first line… I need to know what a UUID is, where to find it,…

Why Pkg.installed(PackageName) has been deprecated ? Shouldn’t be a higher-level function like it (or better Pkg.isavailable("PackageName"), returning directly a bool ) made available ?


The first one had the problem in that it only showed packages that were direct dependencies. It’s API was fundamentally incompatible with showing packages in the manifest since you can have multiple packages with the same name there and the key for installed was the package name. To have an API that gives information about all dependencies (including recursive) you pretty much must use the UUID as the key since that is what identifies the package.

You can however easily recreate the old API as:

isinstalled(pkg::String) = any(x -> == pkg && x.is_direct_dep, values(Pkg.dependencies()))

Note that this only checks if a package with the name pkg is installed, not that it actually is the package you want.


But I am interested in just knowing if a package is already available for using or not.

If name collision is a (remote, i.e. not possible if you just use the standard repository) possibility one could have just a function that returns the number of available packages by name and then use it as:

if Pkg.availablecount("pkgName") == 0
elseif Pkg.availablecount("pkgName") > 1
  @error "More than one package is available with the given name. Please use UUID"

using pkgName

You can use the snippet I gave you then.

It’s also possible to just try to use it and do something in a catch:

    using Foo
   # do something

To add to this discussion:
when I start a program I’d like to enter a vector of packages
then, automatically/generically
-check if it’s installed
-install it if not
-using all packages in vector

Old way, gives deprec warning

pk = ["Knet","Colors","Images"]
using Pkg; for p in pk; haskey(Pkg.installed(),p) || Pkg.add(p); end
using Knet, Colors, Images

New way using @kristoffer.carlsson function

isinstalled(pkg::String) = any(x -> == pkg && x.is_direct_dep, values(Pkg.dependencies()))

pk = ["Knet","Colors","Images", "StatsPlots"]
using Pkg; for p in pk; isinstalled(p) || Pkg.add(p); end
using Knet, Colors, Images

Also I’d like to replace
using Knet, Colors, Images
for p in pk; using(p); end
but it doesn’t work bc pk is a vector of strings

Adding the function isinstalled(pkg::String) each time is a bit of a pain …

1 Like

I am wondering if you are duplicating the work that is supposed to be done by Pkg.instantiate.

julia> packages = [:Example, ]
1-element Vector{Symbol}:

julia> for pkg in packages
           @eval using $pkg

julia> Example.hello("world")
"Hello, world"
1 Like

So is there no one-liner like Pkg.installed() now? I ran the for loop and I got the answer but is there any simpler way of getting the installed libraries?

I’m not aware of any. On the other hand it is a one-liner if you don’t insist on getting exactly the same datastructure as the ancient installed(). Like you could just do:

[dep for dep in dependencies() if dep.is_direct_dep]
1 Like

There is the Pkg.project() which contains a field named dependencies containing a dict with package names and UUID of direct dependencies. So keys(Pkg.project().dependencies) == keys(Pkg.installed()) if I’m not mistaken, and could for the purpose in this thread probably be used as a one line replacement.

This code of mine works wonderfully and hopefully solves almost all the issues raised here:

# Make sure all needed Pkg's are ready to go
neededPackages = [:Gtk4, :Cairo] 
using Pkg;
for neededpackage in neededPackages
    (String(neededpackage) in keys(Pkg.project().dependencies)) || Pkg.add(String(neededpackage))
    @eval using $neededpackage

Suddenly, you get frustrated with something that should be right away, but at least there is always a way to go. Thank you!

Since my last post, I’ve made a few more improvements to the code

input_prompt() = splitpath(Base.active_project())[end-1] * " > "

atreplinit() do repl
    repl.options.iocontext[:compact] = false # Display all Digits
    #colorscheme!("GitHubDarkDimmed") # Optional
    OhMyREPL.input_prompt!(input_prompt, :magenta)

if !isfile("Project.toml")
    # Make sure all needed Pkg's are ready to go in standard Environment. Don't touch it in a Package
    neededPackages = [:Revise, :OhMyREPL, :BenchmarkTools, :IJulia, :Documenter] 
    using Pkg;
    for neededPackage in neededPackages
        (String(neededPackage) in keys(Pkg.project().dependencies)) || Pkg.add(String(neededPackage))
        @eval using $neededPackage

using OhMyREPL