An early prototype for an app to run Julia scripts and manage packages.
jl uses Pkg.jl and only slightly extends the pkg app from JuliaLang/Pkg.jl#4473. It adds init and run subcommands as shown below.
This app requires Julia 1.12 or higher and Juliaup.
pkg> app add https://github.com/visr/Jl.jl
This will place a jl shim in ~/.julia/bin.
If that is in your PATH environment variable, you can run jl from anywhere.
Create a new project in the current directory and add Example.
jl init
jl add ExampleAdd a Julia script called hello.jl with these contents:
using Example: hello
println(hello("Julia"))You can now run the script like this:
jl run hello.jlThis is similar to julia --project hello.jl, except it will first instantiate the project.
This means that you can share the project and script with someone, and they only need to run this command.
Now let's add the Runic formatter to the project.
We can install this as a Pkg app just like jl.
jl app add RunicHowever if we want to avoid relying on global apps we can add Runic to our project. This can make it easier to share setups or use specific versions.
jl add Runic
And we can use the -m flag to run it.
jl run -m Runic --inplace .
Possibly we could support jl run runic --inplace ., where it accepts any apps in the current project or its dependencies.
Ideas welcome!
If a project has a Manifest.toml, we know the Julia version we need for reproducability.
Therefore jl wants to automatically use that version, and install it if needed.
For the best user experience we recommend enabling this juliaup config:
juliaup config autoinstallchannels trueThe following option is not yet released at the time of writing, but if juliaup --version is later than 1.18.9 it should be available:
juliaup config manifestversiondetect trueTo select a Julia version, the same rules as juliaup apply.
This will create a project with Julia v1.12.0, which is installed if needed:
jl +1.12.0 initIf manifestversiondetect is enabled, all operations will use that version unless overruled with e.g. jl +1.12.1 run script.jl.
I was triggered by Miles Cranmer's call to ship a built-in CLI for Pkg.
He made a PR adding juliapkg besides juliaup.
Later on Kristoffer Carlsson made a PR to add a Pkg app called pkg to Pkg.
This uses the experimental Pkg app support added in Julia 1.12.
As a regular user of uv and Pixi I like how they make it easy to not only do package management, but also facilitate running scripts, downloading dependencies as needed.
Currently having to explain to new users about Pkg.instantiate() and the --project flag seems too complicated compared to these tools.
People have argued about changing defaults, but usually security concerns are brought up, listing Nefarious.jl and JuliaLang/Pkg.jl#2024 as examples.
See also discussion in Make activate instantiate by default · Issue #1415 · Pkg.jl.
So we should probably mention that jl should only be used if you trust the project you are in and its dependencies.
I put this code out there to get early feedback.
In the global namespace of CLI tools jl is short and easily associated with Julia, we should consider using it as a community.
It goes a bit beyond the currently proposed pkg app in scope, but if Pkg maintainers consider it in scope for Pkg, that would be a great home as almost all functionality comes from there already.
In the end it would be nice if users installing Julia directly get jl in their path somehow.
The juliaup / juliapkg approach is good for that, though I prefer to explore the Pkg app space for now, coding in Julia.
I don't plan on registering this package in General, so I just went with Jl to match the app name.