Pluto’s built-in package management
Starting with version 0.15, Pluto has a built-in package manager, which means:
- 🎈 Packages are automatically installed when you use
- 🎈 Your package environment is stored inside the notebook file. When someone else opens your notebook with Pluto, the exact same package environment will be used, and packages will work on their computer.
🙋 These two features are designed to make it easy to write and share reproducible notebooks.
Installing and using packages
Pluto will automatically install or remove packages while you work on your notebook. When you import a new package, Pluto will install it:
🙋 Most packages will write installation instructions in their documentation: like “Run
julia> ] install Exampleto install
Example”. If you are using Pluto, you can skip these instructions, and import the package directly, using
Installing packages can take some time, especially when starting Julia for the first time. Click on the status mark next to a package to view the installation progress. You can click on the icon to view the logs.
When you delete the code that imports a package, it will be uninstalled from the package environment. It is recommended to restart the notebook process afterwards to get a fresh start.
You can search for and install any available updates by clicking on the icon. A backup of your notebook file will be created in the same folder as your notebook, in case the new versions do not work as expected.
Good to know
Based on Pkg
Pluto’s package management is a wrapper around Pkg.jl, Julia’s built-in package manager. Packages are installed from the General registry.
🙋 You can discover all available packages on juliahub.com.
Isolated package environment
Every notebook runs in its own isolated package environment. This ensures that your notebook code will not be influenced by packages installed elsewhere. (The
LOAD_PATH is set to
Pluto stores the contents of
Manifest.toml directly in the notebook file. For forwards-backwards compatibility, this is done using two extra “cells” at the bottom of the file, containing the two files as string literals. For example, here is a notebook that imports
fonsp/Pluto file format demo.jl.
🙋 We encourage you to open Pluto, import some packages and look at the file!
Fully reproducible environments
When someone else opens your notebook for the first time, Pluto will install all required packages based on the information in the
Manifest.toml file. This means that the exact same versions of all packages you used in the notebook will be installed, ensuring your work is fully reproducible when shared with others.
Compatibility across Pluto versions
When opening an old Pluto notebook that does not have embedded project files, Pluto will generate them as if you typed those imports for the first time. If a call to
Pkg.activate is made, the notebook will run in ‘backwards compatibility mode’, using the same environment and behaviour as old Pluto versions.
Compatibility across Julia versions
Manifest.toml is designed to be (generally) backwards compatible: you can upgrade Julia and use an old manifest. However, the
Manifest.toml is not always forwards compatible: a manifest generated generated with a newer version of Julia might not run on older versions.
Pluto will always try to load the embedded manifest, and if it fails, it will discard the manifest (leaving only
Project.toml) and try again. This is one reason why Pluto automatically adds
[compat] ranges for each package in the
Package installations are shared between environments
In Julia, packages are always installed globally, while environments (including notebooks) only store version information, not the package code itself. This means that multiple notebooks that use the same version of
Plots will not lead to more disk usage or precompile time. (This is different from
venv in Python/pip, or
node_modules in NodeJS/npm, where every environment contains copies of package code by default.) Julia’s package manager is designed to work well with many package environments on the same computer.
Of course, if different notebooks use different version of the same package, and you work on both in parallel, then source files for both versions will exist on your computer. A small price to pay for simpler reproducibility!
In Julia 1.5 and 1.6, you can clean up package files that have not been used in a while using
import Pkg; Pkg.gc(). In Julia 1.7 and up, this will be done automatically.
Pkg.jl supports additional private or public registries, which can be added in the Julia REPL with
] registry add https://github.com/myuser/MyRegistry.git, and this is also supported by Pluto’s package managemer.
However, note that registries are not stored in the
Manifest.toml files, which means that other people can only open your notebook if they added the custom registry before doing so. Alternatively, you can use a “Pkg cell” (more on this later) where you add the registry before adding packages.