# What is the intended use case for \`JULIA\_LOAD\_PATH\` and \`JULIA\_DEPOT\_PATH\`?

**URL:** <https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [December 4, 2024, 1:26pm UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452 "2024-12-04T13:26:42Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [December 4, 2024, 1:26pm UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452/1 "2024-12-04T13:26:42Z")

</div>

My reading of the docs causes me to conclude the following:

- [Environment Variables · The Julia Language](https://docs.julialang.org/en/v1/manual/environment-variables/)

- `JULIA_DEPOT_PATH` controls where Julia will save packages downloaded via `pkg`

- If set, `JULIA_DEPOT_PATH` specifies where `config/startup.jl` must be located in order for it to take effect

- `JULIA_LOAD_PATH` is a simpler thing, it just controls where Julia looks to load packages when imported using `using` or `import`

- `JULIA_DEPOT_PATH` will also be searched for packages when imported using `using` or `import`

- Presumably `JULIA_LOAD_PATH` is searched with higher priority?

It seems like, overall `JULIA_DEPOT_PATH` is more for use with `pkg` and controlling where packages are installed and downloaded.

On the other hand, if one simply wants to load some local packages or modules created in a target directory, then one should use `JULIA_LOAD_PATH`.

Is my interpretation correct?

---

<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:** [December 4, 2024, 1:31pm UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452/2 "2024-12-04T13:31:45Z")

</div>

I think so, yes. For the most part though, I like using LocalRegistry.jl better than using the `LOAD_PATH` env variable since it helps to keep the workflow more consistent with what you’d use for package development & collaboration.

---

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [December 4, 2024, 1:47pm UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452/3 "2024-12-04T13:47:51Z")

</div>

For context, I have to support two types of workflow. One inside Docker containers, and another on users machines via WSL.

My plan for this:

- Dockerfiles. This is trivial. All the paths, setup, copying of folders, can be defined in the Dockerfile. It is for defining and environment after all. If I need to retain the use of `config/startup.jl` then I probably am forced to use `JULIA_DEPOT_PATH`, or both variables.
- Local WSL. My intention is to export an environment variable. Probably `JULIA_LOAD_PATH`.

Regarding your suggestion of this LocalRegistry package - given the additional context provided do you think is it likely to be simpler solution? (I suspect you’re probably about to tell me no in this case?)

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [December 4, 2024, 1:50pm UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452/4 "2024-12-04T13:50:18Z")

</div>

`JULIA_DEPOT_PATH` allows you to change the location of your `.julia` directory, with everything that goes there. That’s useful if you for example need to place it on a different disk.

Another use case, which is what I mostly use it for, is to simulate that you have a pristine Julia installation. Just point `JULIA_DEPOT_PATH` to an empty directory and you can debug package installation etc. without taking into account the specific state of your `.julia` directory.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [December 4, 2024, 2:38pm UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452/5 "2024-12-04T14:38:16Z")

</div>

> [@world-peace](#):
>
> Regarding your suggestion of this LocalRegistry package - given the additional context provided do you think is it likely to be simpler solution? (I suspect you’re probably about to tell me no in this case?)

It depends on how your environment looks and what kind of constraints you have in your workflows. If you have any kind of git repository hosting available the default would be store your local packages in one or more git repositories and let Pkg handle them the same way as with public packages. A local registry (which would be just another repository) is helpful to organize the local packages, especially if they have dependencies to each other.

---

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [December 4, 2024, 2:42pm UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452/6 "2024-12-04T14:42:29Z")

</div>

We’re using AWS version of Github, which is extremely slow. Unfortunately this wouldn’t be practical as it would genuinely take 20-30 minutes just to clone the code.

---

<div class="post-metadata">

**Author:** ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)\
**Post date:** [December 4, 2024, 3:02pm UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452/7 "2024-12-04T15:02:21Z")

</div>

When I distribute command line utilities written in Julia to my collaborators who don’t program in Julia, my Julia scripts are wrapped up in shell scripts which set the proper `--project` path as well as a dedicated `JULIA_DEPOT_PATH` which points to a subfolder in the folder created by decompressing my tarball. This makes sure that nothing depends on their own `~/.julia` directory (if the latter exists at all). I ask them to first run a setup script which runs `Pkg.instantiate()` to install dependencies into `JULIA_DEPOT_PATH`, then run the actual utility scripts which rely on the dependencies. It’s not essential to do this, but I intended to make my code a “portable installation” which doesn’t touch anything in the user’s home directory.

---

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [December 4, 2024, 4:11pm UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452/8 "2024-12-04T16:11:04Z")

</div>

I like the idea of using the project concept as a substitute for `venv` in Python.

However, I’ve never managed to get my head around how to use it.

Since there is no way to do either of the following things, which can be done from Python:

- Activate a virtual environment in the shell: `source venv/bin/activate`
- Run the `python3` interpreter as “`venv`”: `./venv/bin/python3 main.py`

I don’t think Julia has a similar concept. Having separated environments would be preferable to using the global environment, imo.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [December 4, 2024, 7:03pm UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452/9 "2024-12-04T19:03:42Z")

</div>

I’ll quote [the docs](https://pkgdocs.julialang.org/v1/glossary/) on this:

> **Load path:** a stack of environments where package identities, their dependencies, and entry points are searched for. […] The first entry is your primary environment, often the current project, while later entries provide additional packages one may want to use from the REPL or top-level scripts.

> **Depot:** a directory on a system where various package-related resources live

> **Depot path:** a stack of depot locations where the package manager, as well as Julia’s code loading mechanisms, look for registries, installed packages, named environments, repo clones, cached compiled package images, and configuration files. […] The first entry is the “user depot” and should be writable by and owned by the current user. The user depot is where: registries are cloned, new package versions are installed, named environments are created and updated, package repositories are cloned, newly compiled package image files are saved, log files are written, development packages are checked out by default, and global configuration data is saved. Later entries in the depot path are treated as read-only and are appropriate for registries, packages, etc. installed and managed by system administrators.

In short, the load path and depot path are orthogonal things:

- When you do `import Foo`, the load path tells you how to decide what `Foo` means. It’s a list of environments to look in, and `Foo` is looked for in each environment. As a legacy feature, it can be a directory with a bunch of packages in it, but usually it isn’t, it’s a directory with `Project.toml` and `Manifest.toml` files in it, which is are parsed and consulted for the identity of `Foo` and the version of it to use. Except in the legacy case, you do _not_ find the content of `Foo` in the load path.

- Once you’ve identified what `Foo` is (resolved it to a UUID) and which version of it to use (a SHA-1 tree hash), you still need to find the actual source of that version of `Foo`. For this you need the depot path, which is a list of places to look for things like package contents. Once you’ve found a package, you may also need artifacts that the package uses, which can also be found in depots.

The load path is about converting a package name into a package identity (UUID) and version (SHA-1 tree hash). The depot is about storing and finding package versions and other things that you need.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [December 4, 2024, 7:19pm UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452/10 "2024-12-04T19:19:28Z")

</div>

> [@world-peace](#):
>
> Since there is no way to do either of the following things, which can be done from Python:
> 
> - Activate a virtual environment in the shell: `source venv/bin/activate`
> - Run the `python3` interpreter as “`venv`”: `./venv/bin/python3 main.py`
> 
> I don’t think Julia has a similar concept. Having separated environments would be preferable to using the global environment, imo.

The Julia equivalent of `source venv/bin/activate` is just

```sh
export JULIA_PROJECT=@.

```

The equivalent of `./venv/bin/python3 main.py` is

```sh
julia --project=@.

```

Separate environments are built into the language instead of relying on juggling the `PATH` and other environment variables to simulate local environments.

If you want to automatically activate a local project environment when you are in a directory, you can use [`direnv`](https://direnv.net) (or similar). For example, a `.envrc` file in a project could looks like this:

```sh
export JULIA_PROJECT=@.
export JULIAUP_CHANNEL=1.10

```

This automatically activates the local project and tells `juliaup` to launch the current version of Julia 1.10 by default.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [December 4, 2024, 7:24pm UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452/11 "2024-12-04T19:24:58Z")

</div>

This may be confusing coming from other languages since they don’t usually separate identity and content. In Python, figuring out what `import foo` means is inherently the same thing as finding something in a package directory with the name `foo` and whatever content of that directory has is the code that is used. Julia separates resolving identity and content from finding that content. This allows small, portable Project.toml and Manifest.toml files to unambiguously and reproducibly identify exactly _what_ code should be run. You may or may not have that code, but we know what should run. For more details and motivation, you could check out this video on the design of the code loading and packaging system:

[![](https://global.discourse-cdn.com/julialang/original/3X/6/c/6c7949a9bd61b919e10ea79faa6443218e2bd04c.jpeg "Julia's Pkg – Design & Rationale - Stefan Karpinski") ](https://www.youtube.com/watch?v=_jI8CbN_-IE)

---

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [December 5, 2024, 4:43pm UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452/12 "2024-12-05T16:43:58Z")

</div>

> [@StefanKarpinski](#):
>
> The Julia equivalent of `source venv/bin/activate` is just
> 
> ```julia
> export JULIA_PROJECT=@.
> 
> ```

It’s not really the same. This just causes Julia to think the current working directory is always an environment directory.

If Python had a similar function (it doesn’t) then the equivalent behavior would be for Python to create `venv` and activate it every time the interpreter is run from a working directory which does not currently have a `venv` inside of it.

`venv`’s are relocatable, meaning you can create them anywhere, activate them from anywhere (assuming you know the path)

Doing `export JULIA_PROJECT=@.` is really quite a bit different to that.

---

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [December 5, 2024, 5:07pm UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452/13 "2024-12-05T17:07:32Z")

</div>

> [@StefanKarpinski](#):
>
> instead of relying on juggling the `PATH` and other environment variables to simulate local environments.

Well… it’s a bit swings and roundabouts.

Let me say that I’ve never been a fan of modifying `PYTHONPATH`. I’ve always considered it to be a hack.

I rarely modify it. Usually, if I am working on a project in a directory, I will develop a Python package in a _pythonic style_ which means it can always be found from the same directory as the `python3` interpreter is launched.

This works well for developing software. It doesn’t work so well once a package has matured, especially if you need to consider distributing it.

There are obviously standard ways to do this, but typically it is complicated, or at least more complicated than it needs be, I suspect.

Having a dedicated location to install packages and appending to `PYTHONPATH` is a reasonable solution. It’s very simple and straightforward. It doesn’t cause any problems, although people will tell you it does.

---

<div class="post-metadata">

**Author:** ![non-Jedi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-jedi/32/3645_2.png) [@non-Jedi](https://discourse.julialang.org/u/non-Jedi)\
**Post date:** [December 5, 2024, 6:24pm UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452/14 "2024-12-05T18:24:08Z")

</div>

> It’s not really the same. This just causes Julia to think the current working directory is always an environment directory.

You’re technically right, but it shouldn’t be difficult to see how you can use `JULIA_PROJECT` in a way that’s equivalent to activating a python venv. You just use `export JULIA_PROJECT=/path/to/desired/project` instead.

---

<div class="post-metadata">

**Author:** ![world-peace](https://avatars.discourse-cdn.com/v4/letter/w/9f8e36/32.png) [@world-peace](https://discourse.julialang.org/u/world-peace)\
**Post date:** [December 6, 2024, 11:40am UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452/15 "2024-12-06T11:40:46Z")

</div>

I like your suggestion - but worth pointing out that `venv` is mostly useful for helping to manage external dependencies (things you download with `pip3`). Whereas this environment variable is useful for loading local code. (Stuff you have written on the same machine.)

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [December 6, 2024, 7:18pm UTC](https://discourse.julialang.org/t/what-is-the-intended-use-case-for-julia-load-path-and-julia-depot-path/123452/16 "2024-12-06T19:18:01Z")

</div>

> [@world-peace](#):
>
> worth pointing out that `venv` is mostly useful for helping to manage external dependencies (things you download with `pip3`). Whereas this environment variable is useful for loading local code. (Stuff you have written on the same machine.)

No, the JULIA\_PROJECT affects loading of external packages installed via Pkg. This is exactly analogous to venv and pip3.

It feels a bit like you’re resisting understanding how this stuff works for the sake of complaining about it vis-à-vis Python. May I suggest that you focus more on good faith learning and less on what you wish worked exactly like Python?
