Packages & environments โ
A notebook running on a gate worker manages its own dependencies from the UI โ open the ๐ฆ Packages panel (โฐ โ Packages).
The environment model: fork-and-extend โ
A notebook never pollutes the repo it lives in, and it always runs in one consistent, fully-resolved environment (never a stacked LOAD_PATH, so there are never two versions of a shared dependency). It runs in one of three modes, chosen automatically:
Base โ the notebook has no packages of its own, so it runs directly in the enclosing project. Zero overhead, exactly like a plain script.
Forked โ the first time you add a package, the notebook forks off its parent into its own environment (kept under the depot), seeded from the parent (the parent package is
dev'd in and its deps +Manifestare copied, versions preserved) and resolved as one environment. Adds and pins re-resolve the whole env, so the notebook can override the base. The parent'sProject.tomlis never touched.Detached โ no enclosing project, so the notebook environment is everything.
If the enclosing project's Manifest.toml later changes, a forked notebook auto-resyncs on open: it re-seeds from the parent and re-adds your packages (preserved), keeping it one consistent environment.
The panel โ
The panel shows the environment with provenance, in two groups:
Notebook โ the packages this notebook added (removable โ).
Parent project
โนdirโบโ inherited from the enclosing project (read-only).
The status line reads e.g. 3 notebook ยท 41 from parent (or ยท detached).

Add โ
Pkg.addin the notebook's own env (forking first if needed), then the notebook re-runs so ausinglights up live. The first add can take a while (seed + resolve + precompile); the kernel dot pulses while it works.Remove โ
Pkg.rmfrom the notebook env, confirmed first. Parent rows can't be removed.
The reproducibility footer โ
When a notebook has packages of its own, the .jl carries an auto-maintained, human-readable footer recording just that delta (the packages beyond the parent), with versions + UUIDs:
# โโโก Slate.env ยท notebook packages (auto-maintained โ manage via the package panel)
# CSV 0.10.14 336ed68f-0bac-5ca0-87d4-7b16caf5d00b
# Plots 1.40.5 91a5bcdd-7333-5406-abb4-e4a6da0a7c5c
# โโโกIt round-trips cleanly (it's never parsed as a cell), only changes when your packages change, and is reconstructed on open: if you git clone a notebook whose env dir is gone, opening it rebuilds the environment from the footer (seed from parent, add the pinned packages). For a fully self-contained artifact โ the complete Project + Manifest + local source โ see Export โ self-contained .jl.
Requirements โ
Package management needs a gate worker โ i.e. the notebook lives inside a Julia project (or is detached but gate-capable). For an in-process notebook the panel is read-only and explains why: there is no notebook environment to manage.
Under the hood โ
The UI calls GET /api/<id>/packages (provenance via the set difference active โ parent โ parent-package) and POST /api/<id>/package ({op: "add"|"rm", name}). Operations run through worker tools (__slate_pkg, and __slate_fork / __slate_sync_parent / __slate_reconstruct for the env lifecycle); on success the notebook restales and re-runs and the footer refreshes.