julialang
Install, switch and remove Julia versions with pip: no installer, no apt, no juliaup.
pip install julialang && julialang install && julia
Contents
- Why julialang?
- Quick start
- Everyday use
- Version specs
- Command reference
- Environment variables
- How it works
- For maintainers
- Notes
Why julialang?
Like ziglang does for Zig, julialang makes Julia installable from Python
tooling.
- Tiny wheel.
pip install julialangdownloads a pure-Python wheel of a few KB (py3-none-any), the same on every platform. - No julialang.org needed. The official binaries are mirrored on GitHub by CI;
julialangdownloads from there and verifies sha256 and md5. - Many versions side by side. Install as many as you like, switch with one command, upgrade, downgrade, remove.
- pip-style version specs.
julialang install ">=1.10,<1.13",julialang install 1.12,julialang install ~=1.12.2. - Every stable release. The mirror covers all stable Julia versions, from 0.x to the latest.
- Zero dependencies. Standard library only. Works on Linux (x86_64, aarch64, i686), macOS (x86_64, arm64) and Windows (x86_64, i686) with Python 3.9+.
Quick start
pip install julialang
julialang install # latest Julia, becomes the default
julia -e 'println("hello from Julia ", VERSION)'
Julia itself is not inside the wheel: julialang install downloads it into ~/.julialang.
Everyday use
Install Julia
julialang install # the latest version
julialang install 1.12 # the newest 1.12.x
julialang install 1.10.5 # exactly this version
julialang install ">=1.10,<1.13" # the newest version that satisfies the spec
julialang install 1.10 1.12 # several at once
install only adds versions: nothing is removed, and the installed version becomes the default. Pass
--no-default to keep the current default:
julialang install 1.10 --no-default
Run Julia
julia is a thin shim that runs the selected Julia with your arguments:
julia # REPL
julia script.jl # run a script
julia -e 'print(VERSION)'
JULIALANG_VERSION=1.10 julia -e 'print(VERSION)' # one command with another installed version
Which Julia runs: JULIALANG_VERSION (a spec, must be installed), else the default chosen by julialang, else the
newest installed one. The shim never touches the network. If nothing is installed yet it tells you to run
julialang install (set JULIALANG_AUTO_INSTALL=1 to let julia install the latest on first use instead).
See what you have
julialang # status: installed versions, the default, the latest on the mirror
julialang list # installed versions and the ones the mirror offers
julialang list --installed # only what is on your machine
julialang list --all # everything the mirror has
julialang latest # newest version on the mirror
julialang which # path of the executable `julia` runs
julialang fetch # refresh the cached list of mirrored versions now
Switch version
Switch the default among the versions you have installed:
julialang use 1.10
julia -e 'print(VERSION)' # 1.10.x
julialang use latest
use never downloads: if the version is not installed it tells you to julialang install it first.
Upgrade and downgrade
install keeps old versions; upgrade and downgrade replace the current default:
julialang upgrade # install the latest, make it the default, remove the previous default
julialang upgrade 1.12 # ... or the newest 1.12.x
julialang downgrade 1.10 # same, towards an older version (the spec is required)
The previous default is deleted only after the new version is downloaded and its checksum verified. Asking upgrade
for an older version (or downgrade for a newer one) is an error that points you to the other command; asking for
the version you already use just says so.
Remove versions
julialang uninstall 1.12.2 # one version
julialang uninstall 1.10 1.11 # several
julialang uninstall "<1.12" --yes # a spec that matches many versions asks first; --yes skips the question
Uninstalling the default promotes the newest remaining version to be the new default.
Remove everything
rm -rf ~/.julialang # all installed Julia versions and the cache (Windows: delete %USERPROFILE%\.julialang)
pip uninstall julialang
Installed versions live outside your virtual environment, so pip uninstall julialang alone leaves them in place.
Version specs
Specs work like pip's, with npm-style handling of partial versions:
| Spec | Meaning |
|---|---|
latest (or nothing) |
the newest version |
1, 1.12, 1.12.*, ==1.12 |
the newest 1.x / 1.12.x |
1.12.4, ==1.12.4 |
exactly that version |
!=1.12.4 |
anything but 1.12.4 |
>=1.10, <1.13 |
comparison, as in pip |
<=1.12, >1.12 |
with a partial version the whole line counts: <=1.12 includes 1.12.x, >1.12 starts at 1.13 |
~=1.12.2 |
compatible release: >=1.12.2,<1.13 (and ~=1.12 is >=1.12,<2) |
>=1.10,<1.13 |
comma-joined: every part must hold, the newest match wins |
Quote specs that contain < or > so the shell does not treat them as redirection. Several words are joined with
commas, so julialang install ">=1.10" "<1.13" means the same as julialang install ">=1.10,<1.13".
Command reference
| Command | What it does |
|---|---|
julialang / julialang status |
installed versions, the default and the latest available |
julialang list [--all|--installed] |
installed and mirrored versions |
julialang fetch |
refresh the cached list of mirrored versions |
julialang latest |
print the newest mirrored version |
julialang install [SPEC...] [--no-default] |
download and install (latest if no spec); makes it the default |
julialang uninstall SPEC... [--yes] |
delete versions (aliases: remove, rm) |
julialang use SPEC |
set the default among installed versions |
julialang upgrade [SPEC] |
install the target (latest by default), make it the default, delete the old default |
julialang downgrade SPEC |
the same towards an older version (spec required) |
julialang which |
path of the executable julia runs |
julialang --version |
version of this package |
The cached version list is trusted for one hour by status, list and latest; install, upgrade, downgrade
and fetch always try the network first and fall back to the cache when offline.
Environment variables
| Variable | Effect |
|---|---|
JULIALANG_HOME |
where versions, config.json and the cache live (default ~/.julialang) |
JULIALANG_VERSION |
spec of an installed version that julia should run, instead of the default |
JULIALANG_AUTO_INSTALL=1 |
let julia install the latest version on first use |
JULIALANG_REPO |
GitHub repository to read the mirror from (default MohammadRaziei/julialang) |
JULIALANG_LIST_URL |
full URL of julia-list.json, overriding JULIALANG_REPO (useful for your own mirror or tests) |
State layout: ~/.julialang/versions/<version>/ holds each Julia, and ~/.julialang/config.json records the default
and the installed versions; it is re-synchronised with the folders on every command, so you can also delete a folder by hand.
How it works
Three kinds of GitHub releases act as storage, and two independent workflows do the work:
| Tag | Kind | Holds |
|---|---|---|
__download__, __download_2__, ... |
prerelease | mirrored Julia archives (julia-<version>-<os>-<arch>.<ext>); __download__ also holds julia-list.json (md5 + sha256 and URL of every file). GitHub allows ~1000 assets per release, so the mirror starts the next one after 900 files |
__beta__ |
prerelease | the latest tested build of master (wheel + sdist) |
vX.Y.Z |
release | the published wheel and sdist |
julia-list.json is not in git: it is only a release asset, uploaded again after every mirrored version.
julialang.org (crawled) ──▶ sync.yml ──▶ __download__ (+ __download_N__) + julia-list.json asset
push to master ──▶ wheel.yml: ruff + pytest → build wheel/sdist → smoke test on 5 OSes
(pip install, `julialang install` FROM THE MIRROR, run julia) → __beta__
push of tag vX.Y.Z ──▶ the same, then → GitHub release vX.Y.Z + PyPI
sync.yml and wheel.yml never call each other.
tools/sync.pycrawls https://julialang.org/downloads/manual-downloads/ and https://julialang.org/downloads/oldreleases/, downloads every stable Julia that is not mirrored yet (--min-versiondefaults to 0.0.0 = all), verifies it against the upstream sha256 (and md5 when published), uploads it and records md5 + sha256 injulia-list.json. Only archives with a verifiable hash and a known name are mirrored:.tar.gzfor Linux/macOS,.zipfor Windows (no installers, musl, FreeBSD, pre-releases).--source jsonuses the officialversions.jsonfeed instead. A full backfill takes many hours, so the job stops itself before the 6 h limit (--max-minutes); the next run (weekly cron, a push, or a manual start) continues where it stopped.sync.yml("Sync Julia binaries") runs on every push, weekly and by hand. It only updates the mirror: it makes no package release and starts no other workflow.wheel.yml("Wheel") runs on every push to master and on tagsv*. Its smoke test installs Julia from the mirror on every OS, so it doubles as a health check of the mirror.
Integrity. julialang install checks the sha256 and md5 from julia-list.json. Both come from the same GitHub
repository as the archives, so this protects against corrupted downloads, not against someone taking over the repository.
For maintainers
Set up your own copy
- Create the repo (default branch
master; for a name other thanmohammadraziei/julialangchangeDEFAULT_REPOinjulialang/_state.pyandtools/sync.py, and the URLs inpyproject.toml) and push. - Settings → Actions → General → Workflow permissions: Read and write.
- Every push starts Sync Julia binaries; run it by hand from the Actions tab for a
dry_run(shows the plan) or to mirror in slices withlimit. The first full backfill needs several runs: start it again by hand (or wait for the weekly cron) until nothing is left. - PyPI (optional): add the repository secret
PYPI_PASS(an API token; for a new project use a token with the scope of the whole account) under Settings → Secrets and variables → Actions. Secrets are per repository, so those of another repo do not apply.PYPI_USERis only needed for a non-token login and must be__token__whenPYPI_PASSis a token.
Release a new version
Versions are bumped by hand: edit version in pyproject.toml, commit, then tag and push.
git tag v0.1.0
git push origin master v0.1.0
The tag must equal the version in pyproject.toml (otherwise wheel.yml fails immediately). The tag run publishes the
GitHub release (with generated notes) and uploads to PyPI. Without the PYPI_PASS secret it prints a warning and skips
the upload: add the secret and re-run the tag's run (twine upload --skip-existing and the release step are safe to
repeat).
Without PyPI, the wheel installs straight from a GitHub release:
pip install julialang --find-links https://github.com/MohammadRaziei/julialang/releases/expanded_assets/v0.1.0
Develop
pip install -e . pytest setuptools wheel ruff
python -m ruff check .
python -m pytest -q tests # about a minute; the end-to-end test builds a wheel
python tools/sync.py --dry-run # show what would be mirrored
Notes
- Julia is MIT-licensed, but its binary distribution bundles third-party libraries under their own licenses (see
share/julia/andshare/licensesinside each version). The code in this repository is MIT. - The
juliacommand of this package may shadow anotherjulia(orjuliaup) earlier on yourPATH;julialang whichshows what is actually run. - GitHub pauses scheduled workflows after 60 days without repository activity; if the weekly sync stops, re-enable it in the Actions tab.
Metadata
Release files for julialang 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| julialang-0.1.0.tar.gz | 29.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| julialang-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 48.3 kB
Release files / julialang-0.1.0.tar.gz
| Download URL | julialang-0.1.0.tar.gz |
|---|---|
| Size | 29.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
25ec84077de2eb7927002e25c81ff62e005a7cf4787a536cff33b4da7345c1ef
|
|
BLAKE2b-256 checksum How to use checksums |
a1ab7f3173d53c4d1b21e23af0a4f68f5d9bed9ce9bc7fd364b384d4912d5880
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / julialang-0.1.0-py3-none-any.whl
| Download URL | julialang-0.1.0-py3-none-any.whl |
|---|---|
| Size | 18.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e078e3ebd12c6265bbebc6228c4cef1123ba0f298823c99a2c11f59e4610dc81
|
|
BLAKE2b-256 checksum How to use checksums |
45f3d56f71ddefb953f31f23cd4481766c9c6a3dc80aaabcb469b8e362a6763b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|