Skip to content

Conversation

@pankgeorg
Copy link

Add Persistence for Julia Environment Variables

One of my biggest inconveniences with Julia is that you need to set the knobs very often in many places (startup.jl etc)

This PR adds automatic persistence of all the Julia environment variables except the JULIA_PROJECT one. When Julia is launched with environment variables set (e.g., JULIA_NUM_THREADS=8), they are automatically saved to ~/.julia/juliaup/juliaup.json and reused in future launches, eliminating the need to set them every time.

This is particularly important for me because I always want some knobs to be set; specifically:

  • JULIA_PKG_SERVER=juliahub.com
  • JULIA_PKG_USE_CLI_GIT=true
  • JULIA_NUM_THREADS=8
  • JULIA_CPU_TARGET=generic (yes, generic :) )

and so on

Why not .bashrc?

Well, .bashrc is not cross platform and not standard. It's also significantly harder to edit .bashrc than running a julia command once to set the defaults, especially if you're trying to explain this to a new julia user.

Why not startup.jl?

Some julia environment variables must be set before runtime (startup.jl is too late). This feature allows users to configure their Julia environment once without needing shell scripts or manual environment variable management.

Example Usage

# Set environment variable once
JULIA_NUM_THREADS=8 julia -e 'println(Threads.nthreads())'  # Prints: 8


# Later, without setting the variable
julia -e 'println(Threads.nthreads())'  # Still prints: 8 (persisted value used)

# Override anytime
JULIA_NUM_THREADS=4 julia -e 'println(Threads.nthreads())'  # Prints: 4

Implementation

Changes

src/config_file.rs

  • Added julia_env_variables: HashMap<String, String> to JuliaupConfigSettings
  • Variables stored in JSON under Settings.JuliaEnvironmentVariables
  • Empty maps skipped during serialization for clean configs

src/utils.rs

  • Added get_julia_environment_variables() listing 58 supported variables
  • Excludes JULIA_PROJECT per Julia documentation
  • Covers: parallelization, file locations, Pkg.jl, REPL formatting, debugging, etc.

src/bin/julialauncher.rs

  • Added process_julia_environment_variables() to handle persistence
  • Loads persisted values from config
  • Checks current environment for Julia variables
  • Persists new/changed values automatically
  • Applies resolved variables to Julia subprocess via .envs()

Behavior

  1. When Julia launches, the launcher checks for Julia environment variables in the current environment
  2. If a variable has a non-empty value, it's both used immediately and persisted to config
  3. If a variable isn't set but exists in config, the persisted value is applied
  4. Current environment always takes precedence over persisted values
  5. Persistence happens automatically on every Julia launch with environment variables

Config File Format

Variables appear in the Settings section:

{
  "Settings": {
    "VersionsDbUpdateInterval": 1440,
    "JuliaEnvironmentVariables": {
      "JULIA_NUM_THREADS": "8",
      "JULIA_EDITOR": "vim",
      "JULIA_PKG_SERVER": "https://pkg.julialang.org"
    }
  }
}

Testing

Added comprehensive test suite:

Unit Tests (in src/utils.rs):

  • Validates environment variable list completeness
  • Ensures no duplicates
  • Verifies JULIA_PROJECT exclusion

Integration Tests (new file tests/env_var_persistence.rs):

  • Basic persistence and retrieval
  • Precedence rules (current env > persisted)
  • Multiple variables handling
  • Empty value handling
  • Value updates
  • Config file integrity
  • Cross-version persistence
  • Preservation of other settings

@pankgeorg pankgeorg changed the title feat: persist JULIA_ ENV variables used as user settings feat: persist JULIA_* ENV variables used as user settings Nov 6, 2025
@davidanthoff
Copy link
Collaborator

Hm, ok, this is interesting, but I also think this is too magical and probably out of scope for Juliaup...

I think at the end of the day what this amounts to is a desire to have an option to configure the things that are currently configured via env variables via a global config file. To me that kind of makes sense. But I think really this should be done at the Julia level, i.e. if we want a global config file for these things, then Julia should add support for that.

I could see Juliaup playing in a role in such a setup, for example it could provide command line options to modify these global configuration options.

@KristofferC
Copy link
Member

This PR adds automatic persistence of all the Julia environment variables except the JULIA_PROJECT one. When Julia is launched with environment variables set (e.g., JULIA_NUM_THREADS=8), they are automatically saved to ~/.julia/juliaup/juliaup.json and reused in future launches, eliminating the need to set them every time.

Maybe I missed something but just reading this in isolation it would be very surprising behavior to me. It seems like this is a job for https://direnv.net/ maybe?

@pankgeorg
Copy link
Author

Hm, ok, this is interesting, but I also think this is too magical and probably out of scope for Juliaup...

I think at the end of the day what this amounts to is a desire to have an option to configure the things that are currently configured via env variables via a global config file. To me that kind of makes sense. But I think really this should be done at the Julia level, i.e. if we want a global config file for these things, then Julia should add support for that.

I could see Juliaup playing in a role in such a setup, for example it could provide command line options to modify these global configuration options.

I'm happy to discuss. I would personally prefer juliaup as it's more flexible and feels easier to change. My mental model is that juliaup could be more magical (towards the magic-ness of uv for example), but I understand if that is not really the goal. Having said that, uv doesn't do what this PR does. But I'll argue julia has more knobs to adjust, and that many of them (e.g. JULIA_PKG_SERVER) do have equivalents in the settings.

Maybe I missed something but just reading this in isolation it would be very surprising behavior to me. It seems like this is a job for direnv.net maybe?

Yea, direnv.net seems to address something similar. But I'm coming from a place where I'm trying to target users who do not want or just cannot refine their environments to such precision and detail. So I do think that adding support for "global" julia settings somewhere is important. It needs to be something simple and something that loads before julia does. Again, happy to discuss possible alternatives.

Converting to draft for now, I'm open to ideas!

@pankgeorg pankgeorg marked this pull request as draft November 6, 2025 20:14
@KristofferC
Copy link
Member

So you want a way to persist these type of settings in some other way than using the environment? Having such an option is ok on its own, it is the automatic persistence of these by just setting options and launching julia that didn't really sit so well with me. Having JULIA_NUM_THREADS=4 julia change some global setting would be quite surprising.

@pankgeorg
Copy link
Author

So you want a way to persist these type of settings in some other way than using the environment? Having such an option is ok on its own, it is the automatic persistence of these by just setting options and launching julia that didn't really sit so well with me. Having JULIA_NUM_THREADS=4 julia change some global setting would be quite surprising.

Yes, like Preferences.toml but for things that should be set before julia starts up. Basically an alternative to the ~/.bashrc suggestion here

@davidanthoff
Copy link
Collaborator

Yeah, I could definitely imagine a world where there are lots of other things to configure with juliaup configure.

But also wondering whether juliaup is the right entry point, or whether something like juliaconfig would be better...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants