# Shared and stacked environments

**URL:** https://discourse.julialang.org/t/shared-and-stacked-environments/119874
**Category:** General Usage
**Tags:** workflow, shared-environments, stacked-environments
**Created:** [September 25, 2024, 2:42pm UTC](https://discourse.julialang.org/t/shared-and-stacked-environments/119874 "2024-09-25T14:42:41Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![Eben60](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eben60/32/13475_2.png) [@Eben60](https://discourse.julialang.org/u/Eben60)
#### Post date: [September 25, 2024, 2:42pm UTC](https://discourse.julialang.org/t/shared-and-stacked-environments/119874/1 "2024-09-25T14:42:41Z")

</div>

A common case, you are working on your package, and need some additional packaged during the development only (for plotting, benchmarking, debugging etc.). You put them into your default environment, and soon the `Manifest.toml` file there lists dozens or hundreds of dependencies, with increasing chances of a conflict with the dependencies in your package.

I am thinking of a workflow where your default environment contains just a minimum of packages, maybe just one (see below). Then there are several shared environments for specific tasks - e.g. `@Plots` with the Plots.jl, `@Data` ( DataFrames.jl, CSV.jl, …), `@Benchmarking`, `@Debug` etc.

Then a package for a usage within REPL (and installed into the default environment), which would export the `@using` macro (any objections against the name?), doing roughly following:

- If a package `SomePackage` is already in one of the environments in the current `LOAD_PATH`, then execute `using SomePackage`.
- If a package `AnotherOne` is in a shared environment `@AnotherEnv`, then first push `@AnotherEnv` into the `LOAD_PATH`, then `using AnotherOne`.
- If the package `ToBeInstalled` is not in any shared environment, ask user and install it into `@ToBeInstalled` environment.
- For `@using Pk1, Pk2, Pk3`, find an optimal combination of environments, if some packages are present in multiple shared environments.

Does that all sound reasonably, of have I overlooked something important? Is that functionality or part of that already implemented in some package? (I am aware of similarly motivated [Draft.jl](https://github.com/feanor12/Draft.jl) .) Will it become obsolete after implementation of the incoming [workspace feature](https://pkgdocs.julialang.org/dev/toml-files/#The-%5Bworkspace%5D-section) of Pkg.jl?

* * *

I’m pinging some of those who already discussed relevant topics @lmiq @feanor12 @mkitti  
Some former threads are listed below, but actually there were not many threads about it, suggesting these features are not commonly used:

- [Shared environments?](https://discourse.julialang.org/t/shared-environments/79002)
- [Speculations about the default environment (or a new draft environment)](https://discourse.julialang.org/t/speculations-about-the-default-environment-or-a-new-draft-environment/78967)
- [What is a “shared environment”? When should I use a “shared environment”?](https://discourse.julialang.org/t/what-is-a-shared-environment-when-should-i-use-a-shared-environment/100828)
- [Stacked environments](https://discourse.julialang.org/t/stacked-environments/97955)

* * *

Tentative package name `ShareAdd` or maybe `SharAdd` - is it ok?

* * *

In the following poll, the default Julia environment (i.e. `v1.10`) currently doesn’t count as shared and stacked.

_Poll ([view on site](https://discourse.julialang.org/t/shared-and-stacked-environments/119874/1))_

---

<div class="post-metadata">

### Author: ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)
#### Post date: [September 25, 2024, 3:46pm UTC](https://discourse.julialang.org/t/shared-and-stacked-environments/119874/2 "2024-09-25T15:46:11Z")

</div>

During the recent years, I found Julia temp environments and the autoinstall feature to be very nice.  
Now, I only have few packages in the default env (stuff like Pluto and Revise), and for everything else I just type the package name:

```julia
julia> using DataManipulation
 │ Package DataManipulation not found, but a package named DataManipulation is available from a registry. 
 │ Install package?
 │ (@v1.10) pkg> add DataManipulation 
 └ Select environment:
 > 1: `/var/folders/2j/9vtd991d201dbkh9dnx3wvy00000gq/T/jl_tcW3N8` (/var/folders/2j/9vtd991d201dbkh9dnx3wvy00000gq/T/jl_tcW3N8)
   2: `~/.julia/environments/v1.10/Project.toml` (@v#.#)
   Resolving package versions...
<... Pkg output ...>

julia> # DataManipulation loaded

```

There are a few issues opened regarding making the autoinstall feature even more convenient ([Autocomplete on `using` for uninstalled packages · Issue #51713 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/51713), [Autoinstall prompt should appear in more cases · Issue #53549 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/53549)) – but it’s already great!

Moreover, with BasicAutoloads.jl _(and some setup)_ you get this for any package you want to use often:

```julia
julia> x = KeyedArray(rand(3, 4), x=[:a,:b,:c], y=1:4)
[ Info: Loading AxisKeys for KeyedArray ...
 │ Package AxisKeys not found, but a package named AxisKeys is available from a registry. 
 │ Install package?
 │ (@v1.10) pkg> add AxisKeys 
 └ Select environment:
 > 1: `/var/folders/2j/9vtd991d201dbkh9dnx3wvy00000gq/T/jl_NWdb44` (/var/folders/2j/9vtd991d201dbkh9dnx3wvy00000gq/T/jl_NWdb44)
   2: `~/.julia/environments/v1.10/Project.toml` (@v#.#)
   Resolving package versions...
<... Pkg output ...>

2-dimensional KeyedArray(NamedDimsArray(...)) with keys:
↓ x ∈ 3-element Vector{Symbol}
→ y ∈ 4-element UnitRange{Int64}
And data, 3×4 Matrix{Float64}:
        (1) (2) (3) (4)
  (:a) 0.501477 0.460751 0.948424 0.841584
  (:b) 0.0307299 0.915012 0.150398 0.282693
  (:c) 0.3951 0.0445179 0.90074 0.452201

julia> # x is a KeyedArray now

```

Feels very nice and natural – just type what you want, install & import is done automatically.

Happy to hear if you are planning to further improve on this experience 🙂

---

<div class="post-metadata">

### Author: ![mthelm85](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mthelm85/32/224164_2.png) [@mthelm85](https://discourse.julialang.org/u/mthelm85)
#### Post date: [September 25, 2024, 4:18pm UTC](https://discourse.julialang.org/t/shared-and-stacked-environments/119874/3 "2024-09-25T16:18:49Z")

</div>

> [@Eben60](#):
>
> A common case, you are working on your package, and need some additional packaged during the development only (for plotting, benchmarking, debugging etc.).

I like how Node.js has both ‘regular’ dependencies and then development dependencies. When you install a new package, you can simply include the `--save-dev` or `-D` flag. In the `package.json` file in a Node project, there’s a `dependencies` section and a `devDependencies` section. The packages in the `devDependencies` don’t get installed for someone cloning a repo and running `npm install`.

I wonder if it could be useful to have something similar in Julia. If you’re developing a package it may be nice to be able to `add BenchmarkTools -D` and then just have that package be listed as a development dependency…?

---

<div class="post-metadata">

### Author: ![Eben60](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eben60/32/13475_2.png) [@Eben60](https://discourse.julialang.org/u/Eben60)
#### Post date: [October 13, 2024, 6:58pm UTC](https://discourse.julialang.org/t/shared-and-stacked-environments/119874/4 "2024-10-13T18:58:55Z")

</div>

For my [just announced](https://discourse.julialang.org/t/ann-shareadd-jl-making-easy-to-import-packages-from-multiple-environments/121261) package ShareAdd.jl I am thinking of adding there another macro `@usingtemp`, with the usage like

```julia
@usingtemp Pk1, Pk2

```

which would

1. If the current environment is a temporary one, then install package `Pk1` and `Pk2` there, and import them by `using Pk1, Pk2` .
2. If the current environment is a package under development, then switch to a temporary environment, dev there your package, `goto 1`.

However actually I do not see any advantage of using temporary environments over the workflow currently envisioned in ShareAdd.jl .

Also, for BasicAutoloads.jl - I didn’t try it, but I think it can be made to work with ShareAdd.jl like

```julia
 ["@benchmark"] => :(@usingany BenchmarkTools)

```

What do you think?
