Tips for the Julia startup.jl file

Sep. 05, 2025 (updated Jan. 21, 2026) · Martin Kunz

I have lately spent some time switching between an editor, paper and the Julia REPL, which made me realize how much more pleasant I have made this workflow for myself by stuff I have in the startup file.

What is the startup.jl file?!
For those who are not accustomed with the concept of the startup file in Julia, briefly, it is a script that is run once you enter the REPL. It is stored at $JULIA_DEPOT_PATH/config/startup.jl or if the JULIA_DEPOT_PATH environment variable is not set, the default on GNU/UNIX is $HOME/.julia/. Here you can find more about the startup.jl file.

Some of the changes that I made may be useful to you as well!

Loading Packages for Interactive Use Only

Most people use it for loading packages that they use often enough that they value of having the package functionality available at startup is higher than the price of the REPL startuptime. The library packages that meet this criterium for me are BenchmarkTools and Makie. It is always a good idea when loading packages for interactive use to include them conditionally only when the session is interactive with

try
    if isinteractive()
        using Makie
    end
catch e
    @warn "Error initializing Makie" exception = (e, catch_backtrace())
end

The try/catch control sequence is here, since I switch between different versions of Julia and I do not always make sure that everything is installed.

This way you are only paying the expense when you actually need it and not when running scripts or generating documentation for example.

Other Useful Packages

Non-library packages that may improve your experience with the Julia REPL when using it interactively which I also are important to me are these…

Revise
It has become more of a must have in the community and is also recommended by the official Julia documentation. It manges the changes that you make in your loaded packages and allows the REPL environment to reflect changes that you make in real time.
OhMyRepl
Features include syntax highlighting in your REPL, markdown syntax for documentation and fuzzy searching with fzf of the REPL history.
VimBindings
Enables editing the command line with modal Vim bindings.

Additional Functions

It is also useful to define some functions that you can use for exploration and debugging purposes. For example, I have a subtypetree function which allows me to see all of the subtypes of a particular abstract type to decide on what interfaces I should use for my own implementations.

julia> subtypetree(Integer)
Integer
  Bool
  GeometryBasics.OffsetInteger
  Signed
    BigInt
    Int128
    Int16
    Int32
    Int64
    Int8
  Unsigned
    UInt128
    UInt16
    UInt32
    UInt64
    UInt8
Definition of subtypetree
function subtypetree(roottype, level=1, indent=2)
    level == 1 && println(roottype)
    for s in subtypes(roottype)
        println(join(fill(" ", level * indent)) * string(s))
        subtypetree(s, level + 1, indent)
    end
end

Change the Pages for @less

What is this @less that you are talking about?
If you do not use @less and @edit, you should definitely check them out! These are tools that allow you to inspect the source code of functions implemented in some package (or defined earlier within the REPL). Usually when I have the editor and the REPL open and any of my calls to library functions have unexpected outputs, I would like to inspect what is happening in its implementation. You could surely use GoToImplemention from the language server if you are within the editor context, but I find @less and @edit to be useful in the REPL as well. Most importantly, I use this when I want to look up how some function is implemented in the Julia Base or in some external package, because I want to implement something similar myself.

Also you might want to integrate some tools that you use on your system and use them instead of the defaults. One nice enhancement that I have in this category is using bat instead of less as the pager for in the InteractiveUtils.less function. You can achieve this by including the code

try
    if isinteractive()
        using InteractiveUtils
        function InteractiveUtils.less(file::AbstractString, line::Integer)
            run(`bat --paging=always --line-range $(line): $file`)
            nothing
        end
    end
catch e
    @warn "Error initializing InteractiveUtils" exception = (e, catch_backtrace())
end

in your startup.jl file. This allows me to switch context between reading code that is run and running the code while staying in the REPL using @less instead of @edit which opens the code in the terminal. It gives you syntax highlighting of the output Julia source of the function that you are inspecting.

Imagine that you want to see how the split function is implemented from Base. Perhaps you want to see if there is an iterator with the same behaviour and suspect that it would be present in the implementation. For this reason, you call

julia> @less split("a,b", ",")

From the default InteractiveUtils.less definition that uses the less (or the $PAGER environment variable) command to page the output you can expect something similar to this:

function split(str::T, splitter;
               limit::Integer=0, keepempty::Bool=true) where {T<:AbstractString}
    collect(eachsplit(str, splitter; limit, keepempty))
end

# a bit oddball, but standard behavior in Perl, Ruby & Python:

It has the correct output but it is not very pleasant to read. You can imagine that you are analysing the implementation of a larger function… This would be quite a pain.

If you change the InterativeUtils.less function definition to use bat as described above, you can expect something like this:

File: /home/kunzaatko/.julia/juliaup/julia-1.12.3+0.x64.linux.gnu/share/julia/base/strings/util.jl
function split(str::T, splitter;
               limit::Integer=0, keepempty::Bool=true) where {T<:AbstractString}
    collect(eachsplit(str, splitter; limit, keepempty))
end

# a bit oddball, but standard behavior in Perl, Ruby & Python:

which is way nicer to read…

I hope you enjoyed this non-exhaustive view into the contents of my startup.jl and that you perhaps found something useful for your own that could make the beautiful experience of writing Julia code a little less frustrating…