Best practice for managing multiple projects with package/module dependency

Suppose I have a project directory called ProjectA where I have created the module CoreFunctions.jl (which requires some common packages like DifferentialEquations.jl), which basically provides the core functionality for my current and future work. I also need to install additional packages like Optim.jl which are only specific to ProjectA. So my directory layout looks something like this:

  • projects/ProjectA/src/CoreFunctions.jl:
Module CoreFunctions
using Reexport
@reexport using DifferentialEquations
# more codes
  • projects/ProjectA/simulations/demo.jl:
using CoreFunctions, Optim
# some codes relevant to this project

A while later, I have a second project ProjectB, which requires many codes I have written for CoreFunctions, and I have another new module ExtendedFunctions.jl. I also need to install additional packages specific to ProjectB. So now my new directory look like this:

  • projects/ProjectB/src/ExtendedFunctions.jl:
Module ExtendedFunctions
using CoreFunctions
using FFTW
# more codes
  • porojects/ProjectB/simulations/demo2.jl:
using ExtendedFunctions, GLMakie
# some codes relevant to this new project

What would be the best practice for install required packages and constructing the Project.toml file for both ProjectA and ProjectB (and future projects that will likely build upon the current projects)? I want to keep things simple (e.g. I don’t think I need to use Github for version control yet considering the size of projects) and I want to have self-contained directory for each project: e.g. I only need projects/ProjectA for project A, and only projects/ProjectB and projects/ProjectA/src for project B.

I would make a package out of CoreFunctions and add then the functionalities required, then in my N projects just use MyCoreFunctions package.
Don’t be afraid of git/github, they are very useful also for small projects, and even more when the small project becames a big project …

Fior a tutorial to create packages:

Are you suggesting me to separate CoreFunctions.jl from ProjectA, i.e. having a standalone projects/CoreFunctions with only the essential stuff, and then projects/ProjectA with everything required?

Right now the module CoreFunctions.jl is actually named something else: it’s just called ProjectA.jl located in simulations/ProjectA/src/ProjectA.jl. When I specify ProjectA.jl in the project dependency for project B, it lists everything in project A (including the packages specific to project A but not B) as the dependency, so at the end I’m loading/requiring additional packages that what I really need.

My goal is to have separate project directory for each project (and hence my initial reluctance to separate the universal Module CoreFunctions.jl from the ProjectA project environment), but then I want to minimize having duplicate codes or unnecessary package dependency in my future project directory which require using custom Modules developed for earlier projects. And I’m now sure the most appropriate or standard way to do this. The code is rather specific so unlikely to become something widely used by public, but I want to document it in a way that myself and a few other people in the group can understand.

Yes, I suggest you to create a package, not necessarily public, where you set up functionalities that are needed for several projects.
In that package you can require the libraries that are needed to provide the functionalities you need.
Note that creating a package makes it easier to document and test these “core” functionalities, including GitHub / gitlab continuous integration, and it is even more important if you have to share with oth people.

Then for each project you can require your own package + the other packages specific for the project.