# Reflections on Developer Experience After Building a Large Julia Codebase

**URL:** <https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732>\
**Category:** General Usage\
**Created:** [December 25, 2025, 1:04pm UTC](https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732 "2025-12-25T13:04:35Z")\
**Posts on this page:** 14\
**Page:** 2

<div class="post-metadata">

**Author:** ![cuihantao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cuihantao/32/8783_2.png) [@cuihantao](https://discourse.julialang.org/u/cuihantao)\
**Post date:** [January 2, 2026, 12:57pm UTC](https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732/22 "2026-01-02T12:57:57Z")

</div>

Thank you! I need to try your JetBrains IDE plugin! Does it depend on LanguageServer.jl as well?

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [January 2, 2026, 2:07pm UTC](https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732/23 "2026-01-02T14:07:48Z")

</div>

> [@cuihantao](#):
>
> For the months on Python project X, a single `mamba activate xx` in `.bashrc` will work for all the terminals opened. For Julia, I need to remember to activate the proper environment a lot.

I personally prefer specifying environments or making custom shell scripts that do so, but if you really want a global setting like that, you could make an alias with a default flag or alter the environment variable [JULIA\_PROJECT](https://docs.julialang.org/en/v1/manual/environment-variables/#JULIA_PROJECT). I really wouldn’t mess with startup.jl for this.

> [@cuihantao](#):
>
> If I try to do `activate SpareArrays` in `TestDrive`, it will error because SpareArrays has yet to be add to `TestDrive`. I will then have to duplicate all dependencies from my package being developed.

I can’t tell what you’re trying to do here because there’s a lot of unexplained package names involved, but it sounds really off to duplicate dependencies just to switch environments. `Pkg` mode’s `activate` should be able to switch environments freely in practice. Not sure what you mean by for-debug packages, but shared environments and stacked [environments](https://jkrumbiegel.com/pages/2022-08-26-pkg-introduction/#stacked-environments) sound relevant.

> [@cuihantao](#):
>
> `venv` decouples `pyproject.toml` from what’s actually being installed in the virtual env…But in Julia, when developing my package (in VS Code, the environment is on by default), adding any package will keep modifying Project.toml, either desirable or not.

That’s only because `venv` predates pyproject.toml and never incorporated it. That’s generally considered a weakness, that’s why tools built on pyproject.toml like Poetry base environments on it like Julia does with Project.toml.

> [@cuihantao](#):
>
> here’s the repo for reproducing the error:

First off, very nice MWE. Unfortunately, I either make entirely separate packages or incorporate non-package submodules simply because my submodules and packages never got big or important enough to warrant a monorepo package (and not all monorepos are themselves packages). Someone else who does maintain one should chime in here. In fact, this might be worth its own topic rather than one point in this one, it’ll help get more eyes on the specific issue without having to wade through the other points.

I’ll mention a few things in case they help, anyway. It looks like syncing the Manifest.toml is the problem, and very recently, the [[workspace]](https://pkgdocs.julialang.org/v1/toml-files/#The-%5Bworkspace%5D-section) feature was developed to merge monorepo manifests into one for the base project. Again, I never had to use it, so I don’t know if it’s useful here. Second, a small oddity I’ve noticed is that the base Project.toml has `Statistics` in it despite the source code never importing it. Just in case this is a pattern of duplication, packages don’t need to `add` the dependencies of their direct dependencies, in fact it risks bloat as the direct dependencies can drop their dependencies. The Manifest.toml will contain indirect dependencies on its own.

---

<div class="post-metadata">

**Author:** ![cuihantao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cuihantao/32/8783_2.png) [@cuihantao](https://discourse.julialang.org/u/cuihantao)\
**Post date:** [January 2, 2026, 2:27pm UTC](https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732/24 "2026-01-02T14:27:58Z")

</div>

Very nice. Thanks again!! I will find ways to incorporate your ways of using the environment into my workflow!

That `Statistics` at the top level.. is because in my monorepo setup, the activated environment is the top monorepo. This mimics my use case of running test scripts that use `Statistics` when the top-level environment is active. I will check `[workspace]` as well.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 2, 2026, 2:47pm UTC](https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732/25 "2026-01-02T14:47:06Z")

</div>

> [@Benny](#):
>
> shared environments and stacked [environments](https://jkrumbiegel.com/pages/2022-08-26-pkg-introduction/#stacked-environments) sound relevant

In theory, yes. But in practice they are a nightmare because the actual versions may resolve differently, and a lot of debugging / optimization packages do rely on Julia’s internals and/or get a lot of bugfixes after each release.

The least painful solution I found for 1.12 is

```toml
[workspace]
projects = ["test", "debug"]

```

with the `debug` sub-environment containing the debug tools I use (eg Cthulhu.jl, ProfileCanvas.jl, etc).

---

<div class="post-metadata">

**Author:** ![madppiper](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/madppiper/32/220029_2.png) [@madppiper](https://discourse.julialang.org/u/madppiper)\
**Post date:** [January 2, 2026, 3:11pm UTC](https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732/26 "2026-01-02T15:11:01Z")

</div>

> Thank you! I need to try your JetBrains IDE plugin! Does it depend on [LanguageServer.jl](https://juliaregistries.github.io/General/packages/redirect_to_repo/LanguageServer) as well?

Runs with (LanguageServer or JETLS) or without. You can activate them in the settings.

We have our inbuilt indexing system, which we are slowly upgrading on, so you can actually use it without as well (I do). It covers most of the LS features you are looking for (autocomplete, documentation, navigation etc) and because it is inbuilt. There are also smart templates now that you can use to complete certain aspects more easily.

Give it a go and please give me feedback, so I know what you are looking for in this, too. I already wrote down dot function annotations for the next release 🙂

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [January 3, 2026, 10:13am UTC](https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732/27 "2026-01-03T10:13:08Z")

</div>

> [@cuihantao](#):
>
> **Performance** : The new library is very promising. With a proper variable step integrator for stiff ODE, the simulation performance is probably 100x faster than my Python version, both in small test cases (e.g., for one with ~100 variables, which the Python version takes 1 sec to run and the Julia variant takes 10 ms) and large ones (e.g., another one with ~300k variables, Python’s is 1 hour + and Julia’s is 60 sec.). This is very impressive.

Can I get an MWE there? I think we can maybe just precompile that better.

---

<div class="post-metadata">

**Author:** ![cuihantao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cuihantao/32/8783_2.png) [@cuihantao](https://discourse.julialang.org/u/cuihantao)\
**Post date:** [January 3, 2026, 11:11am UTC](https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732/28 "2026-01-03T11:11:53Z")

</div>

Chris: the performance data you quoted here are run time after warming up, meaning that no precompilation time was included. The run time is very good.

The precompilation time related to DiffEq is not bad; it’s somewhere close to 5 seconds, including the precompilation of sparse AD and solver.

I don’t have an MWE ready to share because it’s hierarchical, and the codebase is not ready yet. I will let you know when ready to optimize!

BTW, how close am I to the largest ODE problem ever simulated with DiffEq? 😁

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [January 3, 2026, 4:01pm UTC](https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732/29 "2026-01-03T16:01:18Z")

</div>

> [@cuihantao](#):
>
> Chris: the performance data you quoted here are run time after warming up, meaning that no precompilation time was included. The run time is very good.

I mean the first run time, ttfx. That’s fixable.

> [@cuihantao](#):
>
> largest

> [@cuihantao](#):
>
> BTW, how close am I to the largest ODE problem ever simulated with DiffEq? 😁

I think the largest I saw was a few hundred million?

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [January 3, 2026, 4:40pm UTC](https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732/30 "2026-01-03T16:40:16Z")

</div>

> [@cuihantao](#):
>
> The first point should be clear. For the months on Python project X, a single `mamba activate xx` in `.bashrc` will work for all the terminals opened. For Julia, I need to remember to activate the proper environment a lot. To get this working, I can think of using `startup.jl` and activate my project being developed, then it gets to my second point.

I typically invoke julia as `julia --project` which activates the Julia project in the current directory or parent directories. You may even want to create a shell alias for this.

```bash
$ touch Project.toml

$ alias julia="~/julia-1.12.1/bin/julia"
$ julia -E "Base.active_project()"
"/home/mkitti/.julia/environments/v1.12/Project.toml"      

$ alias jlproj="~/julia-1.12.1/bin/julia --project"        
$ jlproj -E "Base.active_project()"                        
"/home/mkitti/foo/Project.toml"

```

---

<div class="post-metadata">

**Author:** ![liuyxpp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/liuyxpp/32/9870_2.png) [@liuyxpp](https://discourse.julialang.org/u/liuyxpp)\
**Post date:** [January 4, 2026, 2:12am UTC](https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732/31 "2026-01-04T02:12:57Z")

</div>

It is a bit annoying that the version is hard coded in the alias. If you use `juliaup`, you can simply do (I believe, I haven’t test it though)

```bash
$ alias jlproj="julia --project"

```

---

<div class="post-metadata">

**Author:** ![MilesCranmer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/milescranmer/32/21070_2.png) [@MilesCranmer](https://discourse.julialang.org/u/MilesCranmer)\
**Post date:** [January 10, 2026, 7:27pm UTC](https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732/32 "2026-01-10T19:27:52Z")

</div>

> [@cuihantao](#):
>
> BTW, why do we not have a `pip` and has to run `julia`, `activate` and `install`?

+1 for this. There’s also [Ship a CLI for Pkg.jl by MilesCranmer · Pull Request #1230 · JuliaLang/juliaup · GitHub](https://github.com/JuliaLang/juliaup/pull/1230) which would ship it directly with juliaup and let you work with specific channels/aliases, as well as give you proper command line completions and a help menu via clap.rs:

```julia
# Basic usage
juliapkg add DataFrames
juliapkg test
juliapkg instantiate

# With specific Julia version
juliapkg +1.11 add LinearAlgebra
juliapkg +release test

```

Also there’s apparently now a CLI for [juliapkg](https://github.com/JuliaPy/pyjuliapkg) in case you end up using juliacall (which I highly recommend) for exposing a Python frontend:

```julia-auto
python -m juliapkg add Statistics

```

---

<div class="post-metadata">

**Author:** ![visr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/visr/32/17204_2.png) [@visr](https://discourse.julialang.org/u/visr)\
**Post date:** [January 10, 2026, 7:47pm UTC](https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732/33 "2026-01-10T19:47:34Z")

</div>

I am also playing around with these ideas, see [GitHub - visr/Jl.jl: An early prototype for an app to run Julia scripts and manage packages.](https://github.com/visr/Jl.jl). This goes a bit beyond the Pkg CLIs in that it has e.g. `jl run script.jl` with auto instantiation and such, similar to `uv`. Having such a thing as part of juliaup would be better though.

I also wonder if it would be acceptable to bolt on subcommands in juliaup’s `julia`. In a way `julia +1.12` is already technically breaking since you could have a julia script called `+1.12`. So `julia run script.jl` might be acceptable? Or use the name `jl` if people like it.

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [January 11, 2026, 6:07pm UTC](https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732/34 "2026-01-11T18:07:38Z")

</div>

I think this was mentioned and discarded by some people as undesirable. But for the ways that I use Julia, the following in startup.jl has been convenient:

```julia
let hd = homedir()
    if pwd() == hd && isfile(joinpath(hd, "Project.toml"))
        error("Remove the Project.toml from your home directory.")
    else
        if isfile("Project.toml") && isfile("Manifest.toml")
            Pkg.activate(".")
        end
    end
end

```

I accidentally created a project in my homedir (i.e. when trying to do something quickly in a temp env) several times. So I guard for that… Also, I may have copied this from elsewhere. I don’t recall.

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [January 11, 2026, 6:24pm UTC](https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732/35 "2026-01-11T18:24:18Z")

</div>

> [@cuihantao](#):
>
> Rust, which seems to require decent development in scientific computing infrastructure.

Are you referring to less-developed linear-algebra libraries, differential equations, etc. ?

I think the pressure to develop these things for Rust, and activity towards it, is increasing significantly. For example, the preference for a statically-compiled language in quantum computing is rapidly shifting to Rust. I imagine this is happening in fields with similar requirements.

Speaking vaguely and generally, there seems to be a growing awareness of the difficulties in scaling Julia to large projects (I have not done any of this myself) And it seems that a lot of design and development is going into fixing some of the problems you mention.

My impression from anecdotal data that I can recall is that the general Julia culture is appreciating the need for better practices to support large-scale (or not smallish scale) projects. I recall a few years ago, in online discussions, you’d frequently get pushback if you called for importing only necessary symbols (or using qualified names) in library code.

[Previous page](https://discourse.julialang.org/t/reflections-on-developer-experience-after-building-a-large-julia-codebase/134732.md?page=1)
