# What is in your startup.jl?

**URL:** <https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228>\
**Category:** General Usage\
**Created:** [December 2, 2018, 10:24pm UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228 "2018-12-02T22:24:49Z")\
**Posts on this page:** 16\
**Page:** 2

<div class="post-metadata">

**Author:** ![ianshmean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ianshmean/32/216042_2.png) [@ianshmean](https://discourse.julialang.org/u/ianshmean)\
**Post date:** [October 23, 2021, 6:15pm UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228/21 "2021-10-23T18:15:26Z")

</div>

My startup.jl has become a place for tools that are too simple to be behind an import, and probably too opinionated for Base

````julia
"""
    @subprocess ex
    @subprocess ex wait=false

Execute `ex` in a subprocess that mimics the current process configuration.
Returns the constructed `Process`.
See [`Base.julia_cmd`](@ref) for the subprocess configuration forwarding that is used.

```julia-repl
julia> println("hello from $(Base.getpid())")
hello from 35640

julia> @subprocess println("hello from $(Base.getpid())")
hello from 43056
Process(`/home/user/julia/julia -Cnative -J/home/user/julia/usr/lib/julia/sys.dylib -g1 -e 'println("hello from $(Base.getpid())")'`, ProcessExited(0))
```
"""
macro subprocess(ex, wait=true)
    quote
        local ex_str = $(esc(sprint(Base.show_unquoted,ex)))
        run(`$(Base.julia_cmd()) -e "$(ex_str)"`, wait = $(wait))
    end
end
# See: https://github.com/IanButterworth/julia/tree/ib/subprocess_macro

````

````julia
"""
    @repeat call
    @repeat n call
    @repeat expr call

Repeat `call` until interrupt, or `n` times, and discard the output.
If an expression is given that returns an Integer, repeat that many times.
If an expression is given that returns a Bool, repeat until false.

```julia
julia> @repeat println("hello")
hello
hello
^ChelloERROR: InterruptException:
...

julia> @repeat 3 println("hello")
hello
hello
hello

julia> @repeat 2 + 1 println("hello")
hello
hello
hello

julia> @repeat rand() > 0.5 println("hello")
hello
hello
```
"""
macro repeat(exs...)
    if length(exs) == 1
        quote
            while true
                $(esc(first(exs)))
            end
        end
    elseif length(exs) == 2
        terms = first(exs)
        ex = last(exs)
        if terms <: Integer
            quote
                for _ = 1:$(esc(terms))
                    $(esc(ex))
                end
            end
        elseif terms isa Expr
            quote
                local terms_eval = $(esc(terms))
                if terms_eval isa Bool
                    if terms_eval
                        $(esc(ex)) # do once given that terms has been evaled once already
                        while $(esc(terms))
                            $(esc(ex))
                        end
                    end
                elseif terms_eval isa Integer
                    for _ in 1:terms_eval
                        $(esc(ex))
                    end
                else
                    throw(ArgumentError("@repeat first argument must return an Integer or a Bool"))
                end
            end
        else
            throw(ArgumentError("@repeat first argument must be an Integer literal, or an expression that returns an Integer or Bool"))
        end
    else
        throw(ArgumentError("Too many arguments passed to @repeat"))
    end
end
# See: https://github.com/JuliaLang/julia/pull/41455

````

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [October 23, 2021, 6:28pm UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228/22 "2021-10-23T18:28:35Z")

</div>

@ianshmean, if you have a minute, could you please add a little preamble of explanation for non-experts.  
Thank you!

---

<div class="post-metadata">

**Author:** ![ianshmean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ianshmean/32/216042_2.png) [@ianshmean](https://discourse.julialang.org/u/ianshmean)\
**Post date:** [October 23, 2021, 6:30pm UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228/23 "2021-10-23T18:30:47Z")

</div>

Happy to. Do you mean about the macros themself, beyond the examples in the docstrings?  
Or my rationale for not/abandoning PR-ing them to Base?

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [October 23, 2021, 6:35pm UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228/24 "2021-10-23T18:35:38Z")

</div>

Basically, kindly give some hints on: why a lambda user would like to add your code to his startup.jl? What does it accomplish?

Sorry if it is so obvious to you.

---

<div class="post-metadata">

**Author:** ![ianshmean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ianshmean/32/216042_2.png) [@ianshmean](https://discourse.julialang.org/u/ianshmean)\
**Post date:** [October 23, 2021, 6:47pm UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228/25 "2021-10-23T18:47:56Z")

</div>

For `@repeat` I’ve found the occasional need to quickly run some functions n times, or until something is false, or timedout, particularly when developing hardware controls.

For instance

```julia
julia> @repeat 3 foo()

```

is a little simpler to write than

```julia
julia> [foo() for _ in 1:3];

```

More examples in [https://github.com/JuliaLang/julia/pull/41455](https://github.com/JuliaLang/julia/pull/41455)

* * *

For `@subprocess` if I wanted to do something in a clean julia session quickly I added that largely because I never set up `julia` symlinks to julia binaries, so never have a simple `julia` pointing to the right place.

So

```julia
julia> @subprocess println("hello from a new session")

```

is easier than

```julia
julia> run(`$(Base.julia_cmd()) -e "println(\"hello from a new session\")"`

```

or

```julia
shell> /long/path/to/julia -e "println(\"hello from a new session\")"

```

* * *

The first PR wasn’t very popular. The second doesn’t feel like it would be used widely enough for inclusion in Base (?), so I just kept them local

---

<div class="post-metadata">

**Author:** ![FedeClaudi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fedeclaudi/32/33490_2.png) [@FedeClaudi](https://discourse.julialang.org/u/FedeClaudi)\
**Post date:** [August 29, 2022, 1:27am UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228/26 "2022-08-29T01:27:53Z")

</div>

As seen on [twitter](https://twitter.com/theabhimanyu/status/1563872324213870592?s=20&t=k98GuvDG2e2lzvxVD27VmQ), a few people have been adding [Term.jl](https://fedeclaudi.github.io/Term.jl/stable/) to their startup to style [logging](https://fedeclaudi.github.io/Term.jl/stable/adv/logging/), [errors](https://fedeclaudi.github.io/Term.jl/stable/adv/errors_tracebacks/) and [repr](https://fedeclaudi.github.io/Term.jl/stable/adv/repr/). Leaving this here in case anyone finds it useful.

```julia
try
    import Term: install_term_stacktrace, install_term_logger, install_term_repr
    install_term_stacktrace()
    install_term_logger()
    install_term_repr()
catch e
    @warn "Error initializing term" exception=(e, catch_backtrace())
end

```

Enjoy!

---

<div class="post-metadata">

**Author:** ![pat-alt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pat-alt/32/34264_2.png) [@pat-alt](https://discourse.julialang.org/u/pat-alt)\
**Post date:** [September 29, 2022, 12:22pm UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228/27 "2022-09-29T12:22:27Z")

</div>

So many great little findings in this thread! 😃

I’ve also recently added a package template as per the docs of [PkgTemplates](https://invenia.github.io/PkgTemplates.jl/stable/user/#Saving-Templates-1).

```julia
# Package templates
function template()
    @eval begin
        using PkgTemplates
        Template(;
            user="my-username",
            dir="~/code",
            authors="Me",
            julia=v"1.7",
            plugins=[
                Git(; manifest=true),
                GitHubActions(),
                Codecov(),
                Documenter{GitHubActions}(),
                Citation(),
                RegisterAction(),
                BlueStyleBadge(),
                ColPracBadge(),
            ],
        )
    end
end

```

Then just proceed as always:

```julia
t = template()
t("MyPkg")

```

Works like a charm!

---

<div class="post-metadata">

**Author:** ![ParadaCarleton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paradacarleton/32/20005_2.png) [@ParadaCarleton](https://discourse.julialang.org/u/ParadaCarleton)\
**Post date:** [November 14, 2022, 10:40pm UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228/28 "2022-11-14T22:40:13Z")

</div>

I’ve added [this package,](https://github.com/BioTurboNick/AbbreviatedStackTraces.jl) which makes my life a lot easier.

---

<div class="post-metadata">

**Author:** ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)\
**Post date:** [March 28, 2023, 5:10am UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228/29 "2023-03-28T05:10:28Z")

</div>

Since this thread seems to still be alive, I might as well toss what I’ve currently got going on.

```julia
import Pkg as var"#Pkg" # Don't import globally

isnothing(Base.find_package("Setup")) &&
    var"#Pkg".develop(path=joinpath(@ __DIR__ , "Setup"))

using Setup

@async let
    ESSENTIAL_PACKAGES =
        ["Revise", "DataFrames", "CSV", "BenchmarkTools"]
    EAGER_PACKAGES =
        ["DataFrames", "Statistics", "StatsBase", "BenchmarkTools"]

    for pkg in ESSENTIAL_PACKAGES
        if isnothing(Base.find_package(pkg))
            var"#Pkg".add(pkg)
        end
    end

    @eval using Revise

    for pkg in EAGER_PACKAGES
        if !isnothing(Base.find_package(pkg))
            Core.eval(Main, :(using $(Symbol(pkg))))
        end
    end

    Setup.termtitle(pwd())
end

```

where `Setup` is a whole bunch of setup bundled as a module.

```julia
.julia/config
├── Setup/
│ ├── ext/
│ │ ├── cairomakie.jl
│ │ ├── gadfly.jl
│ │ ├── hdf5.jl
│ │ ├── ohmyrepl.jl
│ │ └── prettycolors.jl
│ ├── src/
│ │ ├── about.jl
│ │ ├── cmdpuns.jl
│ │ ├── colorfulmethods.jl
│ │ ├── pkgstack.jl
│ │ ├── Setup.jl
│ │ └── termsetup.jl
│ ├── Manifest.toml
│ └── Project.toml
├── sysimages/
│ └── <a collection of build scripts>
├── Faces.toml
└── startup.jl

```

All in all, it’s ~900 lines of setup.

This increaces the Julia REPL startup time by ~30%, from 70ms to 90ms.

---

<div class="post-metadata">

**Author:** ![marteaua](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marteaua/32/214927_2.png) [@marteaua](https://discourse.julialang.org/u/marteaua)\
**Post date:** [May 9, 2023, 10:58pm UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228/30 "2023-05-09T22:58:46Z")

</div>

Do you have auto-updating system images in Setup/sysimages ?  
Is it possible for you to give access to your Setup package code ? It looks inspiring !

---

<div class="post-metadata">

**Author:** ![mike\_k](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike_k/32/211864_2.png) [@mike\_k](https://discourse.julialang.org/u/mike_k)\
**Post date:** [May 10, 2023, 2:46pm UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228/31 "2023-05-10T14:46:33Z")

</div>

I always use project specific environments. If there does not yet exist one, I create one. If there already exists one, I activate and instantiate it.

```julia
using Pkg
working_directory = dirname(@ __FILE__ )
cd(working_directory)

if Base.active_project() != dirname(@ __FILE__ ) * "/Project.toml"
    pkg"activate ."
    pkg"instantiate"
end

```

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [May 11, 2023, 5:50am UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228/32 "2023-05-11T05:50:52Z")

</div>

you might find `@ __DIR__ ` useful rather than `dirname(@ __FILE__ )`

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [May 11, 2023, 7:22am UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228/33 "2023-05-11T07:22:50Z")

</div>

> [@mike\_k](#):
>
> `dirname(@ __FILE__ ) * "/Project.toml"`

Also, there’s `joinpath` which is platform agnostic.

---

<div class="post-metadata">

**Author:** ![tecosaur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tecosaur/32/23206_2.png) [@tecosaur](https://discourse.julialang.org/u/tecosaur)\
**Post date:** [May 29, 2023, 11:24am UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228/34 "2023-05-29T11:24:21Z")

</div>

Post-1.9 I don’t have any sysimages, instead I have an environment stack and auto-loading (e.g. starting with nothing loaded, running `CSV.read("some/path", DataFrame)` in the REPL will automatically load `CSV` and `DataFrames` before execution).

I might make my setup public at some point, once I’ve tinkered on it a bit more.

---

<div class="post-metadata">

**Author:** ![frylock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frylock/32/50213_2.png) [@frylock](https://discourse.julialang.org/u/frylock)\
**Post date:** [June 16, 2023, 4:31pm UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228/35 "2023-06-16T16:31:29Z")

</div>

```julia
▷(x, f) = Base.:|>(x, f)

```

Because I like the pipe operation, but lament the fact that it doesn’t have a pretty unicode operator. Can be typed at the REPL with `\triangleright`.

```julia
julia> cos(3) ▷ sin
-0.8360218615377305

```

---

<div class="post-metadata">

**Author:** ![jmanthony3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmanthony3/32/52953_2.png) [@jmanthony3](https://discourse.julialang.org/u/jmanthony3)\
**Post date:** [March 24, 2025, 3:04pm UTC](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228/36 "2025-03-24T15:04:00Z")

</div>

I wish this were added to the Revise.jl docs so I didn’t have to hunt for it each time because it us really useful to activate local environments when developing different projects.

[Previous page](https://discourse.julialang.org/t/what-is-in-your-startup-jl/18228.md?page=1)
