# Independent version requirements for each dependency to avoid downgrades?

**URL:** https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089
**Category:** General Usage
**Created:** [October 2, 2021, 3:45am UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089 "2021-10-02T03:45:01Z")
**Posts on this page:** 19
**Page:** 1

<div class="post-metadata">

### Author: ![robsmith11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robsmith11/32/29641_2.png) [@robsmith11](https://discourse.julialang.org/u/robsmith11)
#### Post date: [October 2, 2021, 3:45am UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/1 "2021-10-02T03:45:01Z")

</div>

I often run into a problem when installing packages with a large number of dependencies where my environment will be forced to downgrade to old versions because a single dependency hasn’t updated its version requirements.

For example, when installing Turing.jl, my default environment downgraded the following packages:

```julia
 [864edb3b] ↓ DataStructures v0.18.10 ⇒ v0.17.20
 [31c24e10] ↓ Distributions v0.25.16 ⇒ v0.22.6
 [1a297f60] ↓ FillArrays v0.12.4 ⇒ v0.8.14
 [a98d9a8b] ↓ Interpolations v0.13.4 ⇒ v0.12.10
 [033835bb] ↓ JLD2 v0.4.13 ⇒ v0.4.3
 [5ab0869b] ↓ KernelDensity v0.6.3 ⇒ v0.5.1
 [189a3867] ↓ Reexport v1.2.2 ⇒ v0.2.0
 [a2af1166] ↓ SortingAlgorithms v1.0.1 ⇒ v0.3.1
 [276daf66] ↓ SpecialFunctions v1.6.1 ⇒ v0.10.3
 [90137ffa] ↓ StaticArrays v1.2.12 ⇒ v0.12.5
 [2913bbd2] ↓ StatsBase v0.33.9 ⇒ v0.32.2
 [4c63d2b9] ↓ StatsFuns v0.9.10 ⇒ v0.9.8

```

Is there any way Julia could manage packages more like Rust’s cargo does? Cargo is able to install different versions of packages in parallel for each dependency requirement.

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [October 2, 2021, 3:49am UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/2 "2021-10-02T03:49:24Z")

</div>

> [@robsmith11](#):
>
> able to install different versions of packages in parallel for each dependency requirement

how does that work? I mean either they work or they don’t right? In Julia because you can potentially `using [all your packages]`, they all have to work, thus the downgrading. If you know you don’t need them to work together, just use separate environment (which is recommended anyway regardless of whether or not the issue you mentioned is actively annoying you)

---

<div class="post-metadata">

### Author: ![robsmith11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robsmith11/32/29641_2.png) [@robsmith11](https://discourse.julialang.org/u/robsmith11)
#### Post date: [October 2, 2021, 3:56am UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/3 "2021-10-02T03:56:32Z")

</div>

Say you want to use both packages A and B in the same environment. They both depend on package C, but package B requires an old version of C.

Julia forces one to downgrade C for both packages A and B. But it could instead install two versions of C and keep track of which version to use for A and which version to use for B. I’m probably oversimplifying, but I believe that’s what happens with Rust.

---

<div class="post-metadata">

### Author: ![robsmith11](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robsmith11/32/29641_2.png) [@robsmith11](https://discourse.julialang.org/u/robsmith11)
#### Post date: [October 2, 2021, 4:03am UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/4 "2021-10-02T04:03:34Z")

</div>

As a side note, this error message isn’t very helpful. It’s not clear to which packages the version ranges are referring:

```julia
(@v1.8) pkg> add Turing@0.18
   Resolving package versions...
ERROR: Unsatisfiable requirements detected for package Libtask [6f1fad26]:
 Libtask [6f1fad26] log:
 ├─possible versions are: 0.1.1-0.5.3 or uninstalled
 ├─restricted by compatibility requirements with Turing [fce5fe82] to versions: [0.4.0-0.4.2, 0.5.3]
 │ └─Turing [fce5fe82] log:
 │ ├─possible versions are: 0.5.0-0.18.0 or uninstalled
 │ └─restricted to versions 0.18 by an explicit requirement, leaving only versions 0.18.0
 ├─restricted by compatibility requirements with AdvancedPS [576499cb] to versions: 0.5.3
 │ └─AdvancedPS [576499cb] log:
 │ ├─possible versions are: 0.1.0-0.2.4 or uninstalled
 │ └─restricted by compatibility requirements with Turing [fce5fe82] to versions: 0.2.4
 │ └─Turing [fce5fe82] log: see above
 └─restricted by compatibility requirements with Libtask_jll [3ae2931a] to versions: 0.1.1-0.4.2 or uninstalled — no versions left
   └─Libtask_jll [3ae2931a] log:
     ├─possible versions are: 0.3.0-0.5.1 or uninstalled
     └─restricted by julia compatibility requirements to versions: [0.3.0-0.3.2, 0.5.0-0.5.1] or uninstalled

```

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [October 2, 2021, 4:29am UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/5 "2021-10-02T04:29:06Z")

</div>

> [@robsmith11](#):
>
> default environment

A common recommendations is to not use you default environment (except for Dev tools like Pluto, IJulia,. Cthulhu, BenchmarkTools etc).  
And instead create an environment for each thing you are doing, with only the packages you need.

It won’t completely solve your problem, but it will vastly decrease it’s impact and frequency.

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [October 2, 2021, 4:32am UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/6 "2021-10-02T04:32:18Z")

</div>

> [@robsmith11](#):
>
> It’s not clear to which packages the version ranges are referring:

They are coloured to match the package names in the REPL (this is the improved version, try this in 1.0 😬)

But if you have any ideas about how to improve this please open an issue on Pkg.jl.  
(It will be lost on Discourse)

---

<div class="post-metadata">

### Author: ![ptoche](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ptoche/32/23554_2.png) [@ptoche](https://discourse.julialang.org/u/ptoche)
#### Post date: [October 2, 2021, 6:52am UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/7 "2021-10-02T06:52:58Z")

</div>

> [@oxinabox](#):
>
> create an environment for each thing you are doing

Out of curiosity, how many different environments do you use?

I try to keep it to under 10, but that’s not nearly enough. Just for plotting I’d probably need half a dozen different environments. In practice though, I use only about 5 and I destroy and reinstall each of these once or twice a month.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [October 2, 2021, 7:02am UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/8 "2021-10-02T07:02:48Z")

</div>

> [@robsmith11](#):
>
> Say you want to use both packages A and B in the same environment. They both depend on package C, but package B requires an old version of C.
> 
> Julia forces one to downgrade C for both packages A and B. But it could instead install two versions of C and keep track of which version to use for A and which version to use for B. I’m probably oversimplifying, but I believe that’s what happens with Rust.

Yes, Rust installs two versions - julia doesn’t allow that, since only one version of a package can be loaded at any given time. When using per-project environments this usually isn’t that much of a problem, but I can see how for larger projects this may be undesirable. Due to the dynamic nature of julia, loading more than one version would (hypothetically) lead to a lot of recompiled code, since you can’t assume that compiled code for version A1 of Pkg A would also work for a dependency requiring version A2. Since julia doesn’t (yet?) ship precompiled binaries or shared objects of julia code like Rust could (and since Rust can check a lot more statically than julia), there’s not much to be done here for now in terms of reducing code size/compile effort.

You should also be aware that while rust allows this, it can lead to problems as [mentioned in their docs](https://doc.rust-lang.org/cargo/reference/resolver.html#version-incompatibility-hazards), with similar explanations and problems as in julia and is best avoided. It’s a philosophical difference that julia doesn’t deal with this problem like rust.

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [October 2, 2021, 7:14am UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/9 "2021-10-02T07:14:30Z")

</div>

> [@Pkg3 vs. Go's vgo](https://discourse.julialang.org/t/pkg3-vs-gos-vgo/10154/2):
>
> People have brought up the prospect of allowing loading multiple different versions of the same Julia package at the same time—largely because that’s what npm does. However, this approach does not mix well with multiple dispatch because each different copy of a package creates different versions of its own types and generic functions, which all the other copies don’t know about. Thus, if you pass a type from one copy of the package to the generic function of another copy of the package, everything blows up—and in the most confusing way since you have an operation that looks like it should work. I don’t think this issue is lessened much by these different versions having different major version numbers, so I think in Julia there can really only be one copy of a given package. If you really want a package rewrite to be completely independent, then rename it and give it a new UUID.

> [@Pkg3 vs. Go's vgo](https://discourse.julialang.org/t/pkg3-vs-gos-vgo/10154/2):
>
> I’ve read the various vgo posts with interest and have mixed reactions. The described approach with “semantic import versioning” can be summarized like this: Your project can depend on two different major versions of the same package at the same time. However, it is impossible to express that you want to allow either of these major versions (not both) and don’t care which. Thus, it is impossible for projects to support adjacent incompatible versions of their dependencies, which strikes …

And there also was another post (which I can’t seem to find right now) where the conclusion was basically to fix the version bounds of the third package, since minor versions should be backwards compatible anyway (though not for 0.x releases, which should be an incentive for packages to release a proper major version 1.0 to make that part of dependency resolution work).

–

And since I accidentally posted in the wrong thread and discourse doesn’t just let me move posts, here is some extra text to fool discourse into thinking I wrote something different.

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [October 2, 2021, 12:57pm UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/10 "2021-10-02T12:57:51Z")

</div>

> [@ptoche](#):
>
> Out of curiosity, how many different environments do you use?

I am a very particular different user profile.  
I rarely really “use” Julia.  
I maintain many many packages.  
Each of which is an environment.  
And I often use it as such doing `dev --local` to try changing packages together.

I have a folder called where I keep a clone of each package I work on.  
With like 100 or so package environments  
Which is the vast vast majority of my use of Julia.

Other than that five or six.  
Much less used.  
Default, one for testing out various mixes of packages in the AD system (this gets recreated a lot).  
One for Invenia’s main production system (sometimes 2), one for our hyperopt system (sometimes 2), one (sometimes 2) for running experiments and analysing results.  
But I rarely use these, because mostly I work on packages.

But environments are **cheap** , every JLSO file is an environment with everything needed to load that file.  
Every Pluto notebook is by default an environment.

I create 2 or 3 environments with `activate --temp` every day to try something or reproduce a bug.

I _am_ not you though. We do different things.

---

<div class="post-metadata">

### Author: ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)
#### Post date: [October 2, 2021, 1:02pm UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/11 "2021-10-02T13:02:08Z")

</div>

I’m not sure what you mean. If you have 20 projects, use 20 different environments. Whenever you start a new project, just to `] activate .` . You have 5 main environments and switch between them depending on the session? Just make new projects.

---

<div class="post-metadata">

### Author: ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)
#### Post date: [October 2, 2021, 7:24pm UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/12 "2021-10-02T19:24:48Z")

</div>

Just to add to what Peter and Lyndon said the other key (I would actually say the most important) reason to have project specific dependencies is reproducibility - run some analysis, finish it, file it away. Have to return to it two years later? Not a problem, your project specific Manifest.toml will ensure that everything just runs.

---

<div class="post-metadata">

### Author: ![ptoche](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ptoche/32/23554_2.png) [@ptoche](https://discourse.julialang.org/u/ptoche)
#### Post date: [October 2, 2021, 10:25pm UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/13 "2021-10-02T22:25:17Z")

</div>

I see, thanks for the detailed answer. I guess my reluctance to keep a large number of environments came from the challenge of remembering which environment to invoke. Do you automate this? like maybe putting something like the following into a function?

```
dir = expanduser("~/my-package-v99/")
push!(LOAD_PATH, dir)
import Pkg
Pkg.activate(dir)
Base.active_project()
using my-package-v99

```

or there’s a simpler way? Thanks.

---

<div class="post-metadata">

### Author: ![ptoche](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ptoche/32/23554_2.png) [@ptoche](https://discourse.julialang.org/u/ptoche)
#### Post date: [October 2, 2021, 10:29pm UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/14 "2021-10-02T22:29:30Z")

</div>

yes sure, I do keep one environment per project and typically have 5 or 6 projects active at a given time. But as I work on a project I add/remove packages, which tends to mess things up by causing unwanted (and unexpected) downgrades. Do you create an environment on the fly every time you experiment with a new package? Thanks.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [October 2, 2021, 11:16pm UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/15 "2021-10-02T23:16:41Z")

</div>

```julia
cd ~/mypackage
julia --project

```

(Having activated it the first time already)

Also if you use VSCode the repl that it starts up already activates the project environment.

> [@ptoche](#):
>
> Do you create an environment on the fly every time you experiment with a new package?

After my .julia folder got greater than 30gb I started to do that. (With `activate --temp`)

---

<div class="post-metadata">

### Author: ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)
#### Post date: [October 3, 2021, 12:14am UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/16 "2021-10-03T00:14:10Z")

</div>

Yes. I get the point that waiting for package operations and precompilation is a pain. One thing that can help is `Pkg.offline()`, which will make it so that `Pkg` tries to use package you already have installed first.

But it would be nice for you to activate a new project by cloning an existing Project.toml, potential taking advantage of any pre-compilation. But then when you modify that environment, it doesn’t change the original toml file. I don’t think something like that exists.

---

<div class="post-metadata">

### Author: ![ptoche](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ptoche/32/23554_2.png) [@ptoche](https://discourse.julialang.org/u/ptoche)
#### Post date: [October 3, 2021, 2:48am UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/17 "2021-10-03T02:48:38Z")

</div>

> [@pdeffebach](#):
>
> One thing that can help is `Pkg.offline()`

Oh, I didn’t know that one, sounds like a good idea 👍

---

<div class="post-metadata">

### Author: ![ptoche](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ptoche/32/23554_2.png) [@ptoche](https://discourse.julialang.org/u/ptoche)
#### Post date: [October 3, 2021, 2:49am UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/18 "2021-10-03T02:49:45Z")

</div>

> [@lmiq](#):
>
> `activate --temp`

yes, I recently started doing that too. 😀

---

<div class="post-metadata">

### Author: ![ptoche](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ptoche/32/23554_2.png) [@ptoche](https://discourse.julialang.org/u/ptoche)
#### Post date: [October 3, 2021, 3:02am UTC](https://discourse.julialang.org/t/independent-version-requirements-for-each-dependency-to-avoid-downgrades/69089/19 "2021-10-03T03:02:21Z")

</div>

> [@lmiq](#):
>
> if you use VSCode the repl that it starts up already activates the project environment

I’ve confused myself more than once when having multiple projects opened in VSCode at once, with the result that I would `Pkg.add` in the wrong environments by mistake. My miserable workaround is I use the _Julia IDE_ for experiments and temporary environments, _IntelliJ_ for when I pull up some older project to remind myself of how I did things there, _Juno_ for my side project and _VSCode_ for my main project. It’s my mental map at this time. Pretty weird, but having multiple projects opened in adjacent tabs inside VSCode hasn’t worked too well for me. 😬
