How to handle with 173 copies of an app
Maintaining 173 apps from the same code is almost impossible. Almost impossible. Almost. So letโs try! ๐คฏ

Sometimes developers need to create different applications with different branding, for different companies, even if they start from the same code.
Imagine creating a management and booking platform for hospitals. But major hospital brands, (The Mayo Clinic, Singapore General Hospital, for example) want their patients to use their own application.
(Yes, usually this kind of corporations have enough resources to create their own platforms, but this is only an example ๐คจ)
Creating these applications initially may not be difficult, the real problem is maintaining a solid structure to keep every one of them up to date.
Letโs assume that all these applications have the same requirements, but each one needs different ids
, name
, colors
, images
and icons
. ๐จ
With these 173 emojis you can get used to the idea:
๐๐๐๐คฃ๐๐๐
๐๐๐๐๐๐๐๐ฅฐ๐๐๐๐๐ค๐คฉ๐ค๐คจ๐๐๐ถ๐๐๐ฃ๐ฅ๐ฎ๐ค๐ฏ๐ช๐ซ๐ด๐๐๐๐๐คค๐๐๐๐๐๐ค๐ฒโน๏ธ๐๐๐๐๐ค๐ข๐ญ๐ฆ๐ง๐จ๐ฉ ๐คฏ๐ฌ๐ฐ๐ฑ๐ฅต๐ฅถ๐ณ๐คช๐ต๐ก๐ ๐คฌ๐ท๐ค๐ค๐คข๐คฎ๐คง๐๐ค ๐คก๐ฅณ๐ฅด๐ฅบ๐คฅ๐คซ๐คญ๐ง๐ค๐ ๐ฟ๐น๐บ๐๐ป๐ฝ๐ค๐ฉ๐บ๐ธ๐น๐ป๐ผ๐ฝ๐๐ฟ๐พ๐ถ๐ง๐ง๐ฆ๐ฉ๐ง๐จ๐ต๐ง๐ด๐ฒ๐ณโโ๏ธ๐ณโโ๏ธ ๐ง๐ง๐ฑโโ๏ธ๐ฑโโ๏ธ๐จโ๐ฆฐ๐ฉโ๐ฆฐ๐จโ๐ฆฑ๐ฉโ๐ฆฑ๐จโ๐ฆฒ๐ฉโ๐ฆฒ๐จโ๐ฆณ๐ฉโ๐ฆณ๐ฆธโโ๏ธ๐ฆธโโ๏ธ๐ฆนโโ๏ธ๐ฆนโโ๏ธ๐ฎโโ๏ธ๐ฎโโ๏ธ๐ทโโ๏ธ๐ทโโ๏ธ๐โโ๏ธ๐โโ๏ธ๐ต๏ธโโ๏ธ๐ต๏ธโโ๏ธ๐ฉโโ๏ธ๐จโโ๏ธ๐ฉโ๐พ๐จโ๐พ๐ฉโ๐ณ๐จโ๐ณ ๐ฉโ๐๐จโ๐๐ฉโ๐ค๐จโ๐ค๐ฉโ๐ซ๐จโ๐ซ๐ฉโ๐ญ๐จโ๐ญ๐ฉโ๐ป๐จโ๐ป๐ฉโ๐ผ๐จโ๐ผ๐ฉโ๐ง๐จโ๐ง๐ฉโ๐ฌ๐จโ๐ฌ๐ฉโ๐จ๐จโ๐จ๐ฉโ๐๐จโ๐๐ฉโโ๏ธ๐จโโ๏ธ๐ฉโ๐
We must take in mind that it will not be 2 or 3 apps, if everything goes well it will be about 173 applications. 173 in Android and 173 in iOS.
(173 + 1) * 2 repositories
The first idea was the following. The base code is stored in a repository that serves as a submodule for different configuration repositories. Each of these is a project that launches the AppCore
Activity
/ ViewController
with the corresponding configuration:

The code is developed on AppCore
, which is convenient, because the maintenance of this repository is simple. But every time you need to make an upload of all the applications you need a script like this:
repositories.forEach {
git pull
git pull submodule
fastlane deploy
git commit
git push
}
This structure has many problems:
- Letโs start by creating the repositories. We will need 1 for the AppCore and 173 for each app. Remember that since we are working on both platforms, all this is doubled.
(1 + 173) * 2 = 348
repositories. ๐ค - This approach โrequiresโ to have every repository downloaded if we want every update to be released quickly. If you are used to Android or iOS projects you will know that each project, and its compilations, takes up a lot of hard disk space. ๐ฉ
- The process of updating each application is really slow, cause each application requires many
git
actions. ๐ฅฑ - Each new version of
gradle
orXcode
usually requires changes in the project, so sometimes you have to make scripts that make changes in all the repositories to adapt them to the new versions. ๐ฅด
2 Repositories with 173 + ~2 branches each
Trying to solve mainly the problems 1 and 2 of the previous system, we started looking for single-repository solutions. We thought that what before was a repository could now be a branch, so we designed something like that:
- ~2 branches for development;
master
,develop
. And all necessary branches likefeature
,hotfix
, etc. - 173 branches with the
master
content customized for each app.

I mean, the master
code is the production code and each of the branches has a master
copy with the appropriate configuration for each app. This way, changes in master
are propagated in each production upload to each of the app branches. So you need a script like this:
branches.forEach {
git checkout
git merge from master
fastlane deploy
git commit
git push
}
This also solves point 4 above, since structural changes in the project are automatically propagated to each of the branches.
But this solution is still not perfect:
- Problem 3 remains: the update process is still very slow, each branch contains a โproject versionโ so, in addition to being a huge repository, each branch contains a lot of information. ๐ฅฑ
- If you have to make changes in every app configuration you need to write a script that goes through all the branches and makes the appropriate modifications. ๐คญ
A repository with a submodule with 173 branches
The previous problems left us with only one option, to find a solution that keeps its base code in only one repository (well, one for android and another for iOS). And the configuration is stored in an external repository. So we set up the following structure:

The repository works like a normal repository, containing an alternative android flavour
and iOS scheme
. This project is accompanied by a configuration submodule. This submodule contains 173 branches which store only the necessary info like ids
, colors
, icons
, firebase configuration files
, etc.
Then, we need a script for every app deploy:
submodule.branches.forEach {
git reset
git submodule checkout branch
merge config with project
fastlane deploy
}
It goes through the configuration branches and each one of them is integrated in the code to upload the application. By not having to make commits on each branch or pushes, the script is much faster and the repository can be kept clean of branches. ๐ฅ
Git Hooks
Git lets you create actions or run scripts when certain git actions happen. Using a post-checkout hook
, you can make the script run every time you change the configuration branch. This way you can test it at any time. ๐ค
Things to keep in mind
Apple App Store Connect
Apple does not allow the publication of these โcopiesโ in the same developer account. ๐คจ You may encounter the following issues:
- Guideline 4.2.6: The solution to this problem is to create different developer accounts for each brand.
- Guideline 5.2: You must prove that you have the right to use the images and logos in the application. Attaching this information once should be enough.
Google Play Developer Console
At the time of writing this article, seems there is no problem in keeping all versions in the same developer account. But this may change at any time. ๐
Why 173?
It is a number high enough to understand the dimension of the solution and above all, it is a prime number, composed of prime numbers. ๐ค
See you in the next post ๐