What is best practice for managing JUCE projects?

I have repository for the source tree of each juce project, which includes source code of mine plus the *jucer file to generate IDE projects as required.
But what about the JUCE folder itself? I have just been doing some small work on a slightly older project and I am spending (an alarming amount of) time mending broken things. I updated JUCE since the last build.
What is best practise here? Do I include the JUCE folder in the repo of every project so that I am able to always build successfully without modification?
I like to keep updated, but would like to be more in control.
Thanks for any tips

I guess many people add JUCE as a submodule to their project repository.


This is a subject that comes up quite frequently in our environment and we are still working it out, but here goes:

  1. Make a general folder for all JUCE-related projects:"
    $ mkdir ~/Documents/JUCE_Projects ; cd !$

  2. Clone JUCE - or, tracktion_engine, if you’re going to use it, which includes JUCE as a sub-module:
    $ git clone https://github.com/juce-framework/JUCE.git
    $ git clone --recurse-submodules https://github.com/Tracktion/tracktion_engine

  3. Now put your project repo ‘alongside’ the JUCE (or tracktion_engine/) directories:

~ mkdir ~/Documents/JUCE_Projects/myAmazingJUCEProject/
  1. Make your .jucer file, save it in your Project directory, configure it to point to the ~/Documents/JUCE_Projects/JUCE (or the ~/Documents/JUCE_Projects/tracktion_engine/modules/juce) directory.
  2. ???
  3. Profit!

Seriously though, the tree should look similar to this:

        \- JUCE
       (\- tracktion_engine/modules/juce) * - up to you
        \- myAmazingJUCEProject

Now and then we find a wonderful tool that should be included, such as FRUT … this goes in the same “JUCE_Projects” directory. This basically means that your projects live ‘alongside’ the JUCE framework (or tracktion_engine of course), and that you’ve always got a stable copy of the JUCE framework to work with …

        \- JUCE
        \- FRUT
       (\- tracktion_engine/modules/juce) * - up to you
        \- myAmazingJUCEProject

This is kind of where I have landed. In the folder where my repo’d working copies are (of various projects) I also have the JUCE folder (similar to above).
My new practice is to name the folder JUCE705 (as of now). I have set the juce modules paths to"…..\JUCE705\modules" in the projects jucer project file.
When a new version of JUCE comes along I place it alongside and rename according to its version, and use it on new projects.
This way I can migrate to newer juce releases in a controlled way. Any repository revision is built correctly because the modules path is in the jucer project file.
Let me know if I’ve missed something…

Wouldn’t it just be easier to have the right version of Juce as a submodule within your plugin project folder? That way you can be absolutely sure that whenever you clone you’re using the right version. It means everything your plugin needs dependency wise is self contained.


I think for hobby work putting the JUCE project alongside the other projects is fine.

But for professional/commercial work you NEED it as a submodule.

To make our lives a little easier we have a juce submodule in every project, and for projucer based projects (we are moving to cmake) we have a script for PC and Mac which looks like this and builds the right projucer version and loads the jucer file:

pushd juce/extras/Projucer/Builds/MacOSX/
juce/extras/Projucer/Builds/MacOSX/build/Debug/Projucer.app/Contents/MacOS/Projucer $1 ./*.jucer

And for windows

set "vsdir=%programfiles(x86)%\Microsoft Visual Studio\2019\Community"
call "%vsdir%\Common7\Tools\VsDevCmd.bat"
pushd juce\extras\Projucer\Builds\VisualStudio2019
msbuild Projucer.sln
"x64/Debug/App/Projucer.exe" ..\..\..\..\..\Infiltrator.jucer

All that path stuff for VS is really ugly and changes like mad between version.

CMake is a better experience although steep learning curve to set up.

1 Like

So when you say “submodule within your plugin project folder”, I take this to mean put a copy of JUCE\modules in my working copy and commit it to the repo, (making the module path changes in the jucer project, of course).
This would be cleaner and more robust, I think.

We use the git submodules system to put the whole JUCE repository inside each project without having to commit JUCE into our repository. Take a while to clone the project but you are guaranteed to get the right version of JUCE for your project, which is important if you are working with anyone else, or need to be able to do a build reliably months in the future.

I use TortoiseSVN so adding JUCE/modules to the project repo should amount to the same, in effect. I’ll see how it performs. Its adding about 30mb to each project but it shouldn’t grow much.

I don’t like to add JUCE to every project, it tends to get very messy when you’ve got multiple plugin projects - my strategy for making sure I always have the right version of JUCE that I’m expecting is to simply use git for the purpose and be sure I have the right tag checked out in the “master JUCE repository” for the particular version of the plugin I’m building - and all plugins building against the same JUCE library (rather than having their own individual copies) is a far more desirable state of affairs than to have everything diverge.

Of course, this also means paying attention to the state of my local JUCE repo before firing off builds, but that’s just good form anyway.

The best strategy is chosen for the circumstances I suppose. This topic was started because I just wanted to make a simple change to an older app and found it broken due to a change in juce. If I had the version of juce it was made with present in the project, I would have added the new feature then done something more important with my time. I would update the juce version at a time when there was a reason to do so, and in a more favourable context.
I can appreciate situations where everything is kept up to date and that would be good, too.

There is always one more opinion in the room than persons, and it beats the tabs vs. spaces discussion.

Submodules are not only a folder, but the parent repository references a specific commit.

  • if you rarely touch a project and want it to be in the exact state like when you left it, then submodule is great
  • if you develop several projects in parallel, it is annoying to check every time, if you updated all submodules. In that case either a central copy you update or preferably CMake with FetchContent is the better route (my preference)

Why not to use one central copy:
Ideally a repository is self contained and can be built without any specific setting on your machine.

  • one day you need to set up a new development machine (new hardware, new team member, etc.) and then it is painful to remember all the things you had to set outside the project
  • When you put the project onto a CI, you have to have it self contained, because you cannot assume anything about the build machine

Thats why I have a monorepo for all plugins with JUCE as a submodule, you dont have to manage different versions and still have all the submodule advantages.

My client doesn’t like his project being in the same repo with my other client :rofl:

1 Like

There’s a git pull config feature for this. I never really understood it so I have a script :slight_smile:

CPM is a good option if you’re using CMake:


No need for submodules, and you can easily specify a specific version. You can also specify branches like so:


I have over 30 active commercial products and I rely on a common JUCE folder for all of them. Since I’m not developing for other entities, that’s the best solution to me… otherwise I’ll end up having this:




We also patched JUCE in several places so it’s really convenient to have just one JUCE folder for all our products.

@lcapozzi @audiothing How do you guys make sure everyone on your team is using the same version of JUCE?

We have 4/5 people working on our JUCE projects and try to always keep JUCE on the latest master branch, but will occasionally switch to develop for bug fixes and whatnot. Coordinating everyone to all update at the same time sounds like it’d be a really PITA.

1 Like

This is part of the reason we’ve just moved all of our products into a mono-repo. We have several other internal and external dependencies which we had to maintain identically between all of our products, and that is just dependency hell. Something as simple as pulling a JUCE update in reality took 20+ commits to roll out across our range of products. Now it takes one (assuming nothing breaks, of course!).

1 Like