How to set up a monorepo with multiple Julia packages and GitHub Actions?

Hey everyone,

I could use some guidance from folks who’ve gone through this before. I’ve been developing locally with a setup that has about ten Julia modules in a single repo. Each module is in its own sub-directory with its own src/, test/, and docs/ folder. Right now I just use plain include() and using across modules — no formal Project.toml or package registration yet.

Here’s roughly what it looks like:

MyApp/
├── Module A/
│ ├── src/
│ ├── test/
│ └── docs/
├── Module B/
│ ├── src/
│ ├── test/
│ └── docs/

Each module is cleanly separated, and everything runs fine locally when I use relative paths and using. Now I’m getting ready to move this to GitHub and want to do it right — with proper Project.toml files, CI/CD testing, and documentation builds (Docs.jl, GitHub Actions, etc.).

What I’m trying to do

  • Keep a monorepo, not split into ten separate repos.

  • Make each module a package with its own Project.toml so I can using Module A etc.

  • Have GitHub Actions “just work” for testing and docs for all modules.

  • Avoid mistakes or rework others may have already gone through setting up monorepo workflows.

My questions

  • What’s the best way to structure this monorepo so that CI/CD (GitHub Actions, coverage, docs) works cleanly for all sub-packages? Should I have one top-level Project.toml that references the sub-packages, or should everything be independent?

  • How do people typically handle cross-module dependencies inside a monorepo (e.g., Module A depending on Module) — through dev paths or local registries? (not all modules are dependent upon each other, but some are at higher levels)

  • Any examples of monorepos in the Julia ecosystem that follow this pattern (or close to it)?

I’ve seen plenty of examples of single-package setups, watched videos on Projects and Packages, but not many covering multi-package “app” style projects like this. I’ve had my head down developing, but need to plan for this migration now. I’m certain others have done this though, so I would love to hear from anyone who’s already worked through the packaging + CI details for something similar or if I have missed existing threads or docs that address this.

Thanks in advance — I’d really like to get this right before I migrate everything to GitHub!

— Steve

1 Like

I think monorepos are possible since v1.11.
You should have a Project.toml for each submodule and an additional top-level one.
Since 1.11, a Project.toml has the “Sources” section (11. Project.toml and Manifest.toml · Pkg.jl), so that you can add unregistered dependencies in a portable way.

I’ve never tried a monorepo approach, but it seems that Documenter.makedocs (Public API · Documenter.jl) has the capability you need.

For testing, it should be simply using Pkg; Pkg.test("ModuleA"); Pkg.test("ModuleB"); ... Pkg.test() from within MyApp environment. That will run test/runtests.jl files for the submodules (13. API Reference · Pkg.jl).

1 Like

Also check out the new workspace feature introduced in 1.12 that simplifies this a lot. This may remove any need for specifying sources in the first place.