How to Retrieve a List of Installed Packages in Julia
Overview
The more often you reinstall Julia, the more frequently you need to reinstall packages and deal with annoying details. It’s therefore convenient to create a header that inspects the installed package list and automatically installs any missing packages, but the problem is that obtaining that package list is not straightforward.
Code
Pkg.installed()
using Pkg
Pkg.installed()
keys(Pkg.installed())
julia> Pkg.installed()
┌ Warning: Pkg.installed() is deprecated
└ @ Pkg ...\Pkg.jl:829
Dict{String, VersionNumber} with 26 entries:
"CSV" => v"0.10.15"
"PlotlyKaleido" => v"2.3.0"
"Random" => v"1.11.0"
⋮ => ⋮
This cleanly returns the currently installed package list as a dictionary of names and versions (dictionary), but as the warning indicates, this function will be removed soon. Since you can just use keys to get only the keys of the dictionary, this is overwhelmingly convenient compared to the other methods described below. For programs you run alone, feel free to use it for now; when it is eventually removed, switch to another alternative.
Pkg.dependencies()
Pkg.dependencies()
getproperty.(collect(values(Pkg.dependencies())), :name)
julia> Pkg.dependencies()
Dict{Base.UUID, Pkg.API.PackageInfo} with 315 entries:
UUID("a4ae2306-e953-59d6-aa16-d00cac43593b") => PackageInfo("libaom_jll", v"3.12.1+0", "4bba74fa59ab0755…
UUID("0c81fc1b-5583-44fc-8770-48be1e1cca08") => PackageInfo("InputBuffers", v"1.1.1", "e5392ea00942566b6…
UUID("7c1d4256-1411-5781-91ec-d7bc3513ac07") => PackageInfo("DynamicPolynomials", v"0.6.3", "ca693f8707a…
UUID("53ae85a6-f571-4167-b2af-e1d143709226") => PackageInfo("SciMLStructures", v"1.7.0", "566c4ed301ccb2…
⋮ => ⋮
This returns a dictionary of package information that captures all package dependencies. If you take the values with values and then use getproperty to extract the :name property, you can obtain an array of package names. The problem is that, despite ostensibly reflecting all dependencies, this package list does not represent the packages the user actually installed; instead it references the Julia environment’s Mainfest.toml, so it may not match reality.
Pkg.status()
Pkg.status()
buf = IOBuffer()
Pkg.status(; io=buf)
output = String(take!(buf))
_output = strip.(getproperty.(collect(eachmatch(r"] .+ v", output)), :match), Ref([' ', ']', 'v']))
julia> Pkg.status()
Status `C:\Users\rmsms\.julia\environments\v1.12\Project.toml`
[336ed68f] CSV v0.10.15
[861a8166] Combinatorics v1.0.3
[a93c6f00] DataFrames v1.8.0
[7806a523] DecisionTree v0.12.4
[b4f34e82] Distances v0.10.12
⌃ [7a1cc6ca] FFTW v1.9.0
[38e38edf] GLM v1.9.0
[86223c79] Graphs v1.13.1
[033835bb] JLD2 v0.6.2
[b964fa9f] LaTeXStrings v1.4.0
[470638dc] NoiseRobustDifferentiation v0.2.4
[e9f21f70] OpenAI v0.12.0
[9b87118b] PackageCompiler v2.2.2
[a03496cd] PlotlyBase v0.8.21
[f2990250] PlotlyKaleido v2.3.0
⌃ [91a5bcdd] Plots v1.40.19
⌃ [08abe8d2] PrettyTables v3.0.8
[92933f4c] ProgressMeter v1.11.0
[2913bbd2] StatsBase v0.34.6
[69024149] StringEncodings v0.3.7
⌃ [0c5d862f] Symbolics v6.54.0
[fdbf4ff8] XLSX v0.10.4
[ade2ca70] Dates v1.11.0
[37e2e46d] LinearAlgebra v1.12.0
[9a3f8284] Random v1.11.0
[2f01184e] SparseArrays v1.12.0
Info Packages marked with ⌃ have new versions available and may be upgradable.
The last method I found is to capture the package list printed by Pkg.status() at the REPL as a string. Use an IOBuffer to capture the output of Pkg.status() into the buffer, convert it to a string with take!, then use the regular expression r"] .+ v" to get all lines containing package names and versions. After that, use getproperty to extract the :match property and strip to remove leading/trailing whitespace and the characters ] and v, yielding a clean array of package names.
It’s somewhat involved, but once you understand the idea and step through it line by line it’s not a particularly tricky technique, and at least at the time of writing this post it’s the cleanest method with the fewest side effects.
Below is an implementation of this process as a function called installed for easy reuse.
function installed()
Pkg.status()
buf = IOBuffer()
Pkg.status(; io=buf)
output = String(take!(buf))
return strip.(getproperty.(collect(eachmatch(r"] .+ v", output)), :match), Ref([' ', ']', 'v']))
end
Environment
- OS: Windows
- julia: v1.20.0
