MacUpdater icon

Tech Sale & Licensing

Buy or license MacUpdater tech for your company


MacUpdater is a system for keeping all apps on a macOS computer up-to-date - it can update 6.700 different apps to their latest version and reliably display the latest version (if not equal to the installed version) of more than 100.000 more apps. A system like that cannot work fully automatically, it needs maintenance so that all the information is current and all the updates are added (and sometimes removed) in a timely fashion. The value of MacUpdater does not lie in the app our users see on their Macs, but in the infrastructure we've built to to enable and maintain it.

MacUpdater 3.x will be discontinued on 01-01-2026 after 8 good years. We've completely solved all technical issues related to perfect app-updates and built a reliable and trusted system loved by tens of thousands of our users. But we've failed in building a sustainable pricing and sales model (instead trying to sell one-time-purchases). And we've not done any marketing to start to widen our audience. Also we've failed to enter the corporate / enterprise market. With all interesting technical challenges being solved we feel it is time to move on and leave the boring work of continuing, marketing and monetizing the project to someone else. Especially since it has become apparent that MacUpdater can only be sold profitably with a 'subscription-model', and we will not sell subscription software for ethical reasons. So, we are open to either license the technology to everyone who needs it or sell the full project to anyone who wants to continue it for the benefit of macOS users everywhere.

If you want to continue MacUpdater or license the technology, get in touch at: root@corecode.io



EFFORT

If you need a system similar to MacUpdater and are thinking about building it yourself, read the "EFFORT" section and especially the "Problems & Solutions" subsection below to learn why building such a system is much more work than expected. We can guarantee that licensing our finished solution makes more sense.

Click here to expand the 'Effort' chapter.



INFRASTRUCTURE & COMPONENTS:


CLIENT APPLICATION:
The MacUpdater app is the only thing our customers see but is only a small part of the MacUpdater project. It has been refined and polished over the past 7 years for optimum usability and fast workflows even in edge-cases and more advanced scenarios. The application operates based on a thin client principle for maximum speed and control. The MacUpdater app consists of 40.000 lines of code its 20.000-word interface is available in 10 languages. Rewriting the application from scratch is not trivial, especially without having access to all the knowledge and lessons we learned in the past 7 years.


BACKEND SERVERS:
The backend servers located on macupdater-backend.com serve the config-file, the version-number database and the download-info files to the MacUpdater client application. The backend architecture is modeled for high security, high availability and scalability also to ensure that future growth would not necessitate a hasty switch to another backend. We estimate that the current backend architecture could scale to a 50-times higher concurrent user count - possibly even higher. Another achievement of the backend server is to provide service only to legitimate client versions of MacUpdater while excluding unauthorized access and yet still allowing free/demo users to try MacUpdater without any form of user registration.


VERSION-NUMBER DATABASE:
MacUpdater's version number database helps MacUpdater to know the latest version of any app even when that app is not fully supported through other means. Our database has grown and was refined for 6,5 years and contains 1,7 million entries for 150.000 different apps. The database has been modeled for optimum access speed by the clients and has been updated both manually, semi-manually and automatically with custom information resulting from our maintainaince and support, so recreating this from scratch would not be trivial even when having access to a large number of clients to contribute to the database. One critical part of such a database is also to allow submission of official released app versions, while excluding beta or unofficial releases.


DOWNLOAD-INFO FILES:
One part of MacUpdater is to know the latest version of each app, another part is to provide support for actually updating to the latest version of the app. MacUpdater can update 6700 different apps (and non-app software) and for 4.000 apps we maintain the information about the latest version number, download location, name, size, hash, signature, install location, etc ourselves. All those 4.000 files need to be updated each day by finding (only) official updates. Also, files need to be downgraded when an update is withdrawn or deleted when an app is no longer available for download. Updating, downgrading, removing and adding those files is a central part of our daily maintenance and the cumulative knowledge in those 4.000 files would not be trivial to recreate.


CONFIGURATION FILE:
Our config-file is the central component of MacUpdater and the crown-jewel resulting from 2500 days from completely uninterrupted daily maintenance and effort. The config file tells MacUpdater how to each app in order to enable perfect support. The config file contains entries for 75.000 apps, annotating them with 135.000 tags. Each app can be annotated with 100 different possible tags to ensure perfect functionality for that app (more below). Updating the config-file is a central part of the daily maintenance, constantly adding, removing and changing tags to ensure perfect support for each app. Normally the config-file is updated at least half a dozen times per day so that every user initiating a scan from MacUpdater has a perfect experience.


LICENSING INFARSTRUCTURE:
Our licensing backend runs on AWS Lambda to provide the highest possible availability for this critical part of our infrastructure, is connected to our purchasing systems at Stripe & FastSpring and integrates with custom scripts and GUI apps that our team uses to verify, update, create and reset serial-numbers and activations.



MAINTENANCE INFRASTRUCTURE:
As alluded to above, the amount of daily maintenance required to make MacUpdater work perfectly is quite staggering. This results in a problem that the daily maintenance does actually take more than a day to perform, even with a well-trained team. Therefore we had to develop automations, workflows and toolchains to optimize that maintenance as much as possible and sensible. A lot of tasks are fully automatic, many are semi-automatic and many others still require human intervention. Some parts of our pipeline are powered by OpenAI, but the vast majority will still require human intelligence in the foreseeable future. Our toolchain consists of dozens of apps, tools, scripts and templates and many custom shell aliases. The whole toolchain consists of more than 25.000 lines of ObjC, C, Python, Ruby and SH. The central part is a 10.000 line tool that is run every day and which performs hundreds of checks that have been optimized since 2018 and whose output need to be processed by the team. Another integral part of the maintenance pipeline are the maintenance servers that are also used to automatically download, extract and verify app updates around the clock, making sure verified updates are delivered to our users as quickly as possible. Those servers operate autonomously but will require intervention for all unexpected failures. By our estimation the efficient maintenance infrastructure is the part of MacUpdater that would be most complicated to replace.



PROBLEMS & SOLUTIONS:

Even with multiple decades of experience of software development and excellent knowledge of macOS technology, it can be easy to underestimate the amount of work required to make something like MacUpdater by at least an order of magnitude. Lets shortly cover the problems that any system providing what MacUpdater provides needs to solve effectively.

• Extracting Version Numbers
A central part of any system to find updates will be extracting and comparing version numbers. The great news here is that macOS basically mandates easily readable metadata that includes versioning information for all macOS software. However, what should be a simple read of the 'Info.plist' is complicated by the fact that the Info.plist can be stored in multiple formats and locations (especially in old or iOS binaries - did we mention you need to support those iOS apps that can be run on ARM-based Macs?) as well as being overridden in InfoPlist.strings files. Furthermore, apps contains at least two different version numbers (bundle version and short version string) and while in theory only the former should be used to find the latest version of an app, this is often not the case. You'll need to find out and constantly re-evaluate which version information should be used for which app, not only out of those two common values but there are at least two more uncommon ones too. Some apps do not contain any version information at all, in which case you can synthesize version information from the code-signature date. Other apps do not obey macOS standard versioning system at all and contain their version information in custom locations and formats, so you'll need to write custom code to extract meaningful numbers for each of them. If an app does not have version numbers and it is not possible to synthesize version numbers from the code-signature or via custom code, you still need to handle the app differently based on whether the latest or previous versions of the app had no version numbers.


• Comparing Version Numbers
Comparing version numbers should be very easy, since macOS mandates that the CFBundleVersion needs to be numerically increasing for each newer version. Tens of thousands of apps disobey this rule. Apart of selecting the right version field (see above) to use for comparison, you'll need to deal with different versioning schemes. Sometimes an letter suffix like 'a' could mean 'alpha version' and thus older. Sometimes it means it is an additional bugfixed version and thus newer. Many developers forget the dots in their version numbers, so they'd release version 1.1, 1.11, 1.2 in sequence although '2' is lower than the '11' that they clearly forgot to add a dot in. Many version numbers that according to Apple's rules should only contain numbers and dots are randomly infused with other strings, possibly changing format with each release. Without developing an elaborate and layer-able transformation system (and selecting and updating which one is right for each app at each point in time) you cannot compare the version numbers for most apps. While comparing version numbers you'll need to deal with ignoring pre-release versions based on custom patterns (different for each app!) as well as specific releases that are known to be beta versions that are not properly labels (which needs to be a manually updated list for each app). You'll also need to deal with numbering mistakes, where the vendor has made releases that is higher in version number, but actually older. Those releases do not only need to be ignored as a possible update (because it is actually older) but also users that have those versions need to be always shown an update to the latest version (which is newer despite having a lower version number). Those mislabeled releases need to be identifiable one-by-one or based on patterns. Since there are up to 4 version numbers per app and they are often affected by mistakes and conflicting, we need a way to find out which release is actually the latest so that the appropriate mechanisms can be selected for this app. However, how to find out the latest version if the version numbers are often faulty? It would be great if we had a release-date for each release. However, file-dates are extremely unreliable, often differing for each file in an app bundle, and also in different cases either the file creation or modification date would be appropriate. Sometimes file-dates are already broken by the vendor, in other cases they get broken by the users. Code-signature-dates are better but not foolproof either. You'll also need to consider that some users modify their installed apps, or do obtain apps from, euphemistically speaking, "unofficial sources". To find out which release is the latest one you'll sometimes need at all the information like 4 version numbers, get info string, copyright info, file-dates from a variety of database submissions, code-signature date, vendor homepage, etc, etc until you know what is going on and can select the appropriate mechanisms for this app to use so that the latest version shows up correctly for everyone.

• App Identity
If you want to show updates for apps, you need to identify apps. No, you cannot just use the app-name as an identifier, as the same name is very often shared by distinct apps. But the great news here is that macOS basically mandates an unique identifier for each app, so there is nothing to do here. Wrong. Just like version numbers, the 'bundle identifier' is more often used incorrectly than correctly. We have two different issues: a.) distinct apps that use the same identifier (although they shouldn't) or b.) the same app using a different identifier in different releases. Lets look at both cases. Sometimes different apps have the same identifier, either e.g. using a template, nondescript or generic identifier either due to poor choices from the developer or because the system they used to generate the app was broken in that way. Also, sometimes a vendor uses the identifier for a product even if that product exists in different variants or editions. You don't want to ask the user of "AppName Pro" to update to a newer version if that newer version currently only exists for the "standard" and not the "pro" version of that app. You'll want to treat the ESR/Beta/Standard/etc editions of all major browsers differently even if their identifiers might be the same. So, you'll need to develop a system to treat apps differently even if their identifiers are the same, having a long list of template mechanisms which you can apply to each app as well as the possibility to have custom 'distinction' code for different apps. We found that at least 650 apps suffer from the "non-unique identifier" problem. The opposite and even far more common problem is that different releases of an app have different identifiers. Some vendors are very confused and put the version number of their app in their identifier, so each release has a different identifier. Some vendors put the generation of their app in their identifier, often to circumvent Apple's rules to disallow paid app upgrades in the Mac App Store. Some vendors just randomly change their identifier, like a game of 'mistake of the day'. You'll need to find out which of hundreds of thousands of identifiers are actually the 'same' app. MacUpdater pledges to find updates even if the app has changed its name, even if the company has changed its name or even if an app has been replaced with an 'successor app' (which is basically just a rename). Finding and updating the list of possible identifiers per app is a central task of our maintenance and we are currently aware of ~18.500 cases where an app has changed identifier. Confirming or denying these 'override' cases is sometimes easy but sometimes quite tricky like a detective game where you need to look not only at all available meta-data of all releases of both identifiers but also at the app icons, vendor homepage (possibly archived if the app is old), or do a deep dive into archived information in the dark software corners of the web. App identity is particularly difficult with regards to open-source software and GitHub in particular, where a.) apps are often 'forked' without performing the required change-in-identifier and b.) apps are often compiled or obtained in unofficial releases which make it to the version number database.

• Minimum Requirements, Architecture Requirements & Languages
Users will expect to not see (or update to) the latest version of an app, but the latest version that runs on their installed macOS version. You'll basically need to separate each app for each supported macOS version (and MacUpdater has supported up to 7 major macOS versions concurrently), and maintain the latest version and the download URL independently for each of those macOS versions. This is again complicated by developers making mistakes and incorrectly using the 'LSMinimumSystemVersion' embedded into the app. Even the more complicated-to-obtain LC values in the MachO headers are not necessarily reflect the real requirements. Also, many vendors ignore Apple's recommendation of providing a single 'universal' download for both Intel and ARM-based Macs, so you'll need to store multiple download locations and differing minimum system requirements based on the CPU architecture. Even Apple's rules that every Mac app must support all languages in a single multilingual download are often ignored, so you need to take care for example not to overwrite a japanese user's app installation with an english-language download or even not to bug users by displaying update information if the update does not exist in their preferred language.

• Mac App Store
Finding and applying updates is something that is extremely useful for downloaded apps, but less useful for Mac App Store (short: 'MAS') apps, because the store already updates those apps - depending on the user's settings this is even done fully automatically. However, for some unfathomable reason, many users still expect perfect support for finding the latest version of apps that have been downloaded from the MAS. Also, since the Mac App Store disallows paid upgrades, developers often upload the same app as a 'different' app to the store, just putting the major version number in the name of the app instead. You'll have to find those major upgrades that the MAS itself can't show to provide a genuine value to your customers. Even if you want to skip that functionality, there is the fact that apps often change out-of or into the store, sometimes multiple times. If a user downloads an app, and the app is later only distributed in the MAS, you'll want to show him this latest version only available in the store (by retrieving the version numbers from Apple's MAS API). Similarly, if an app has changed out of the store, you'll need to display those updates even if the user has initially obtained the app in the store. Several things make this complicated: many apps are distributed both inside and outside the store, and those updates often do not happen synchronously. You don't want to bug users to change their app source into or out of the store because of 'slight' delays or because of 'minor' differences in version, but still want to catch the other cases. You cannot rely on an app being removed from the store if the newest version is available only outside from the store. Furthermore, some apps use the same identifier for the MAS and their downloadable version, while other apps use distinct identifiers (you will need to match all those pairs up). Sometimes this changes over the lifetime of an app. To display the latest version of a MAS app, you'll have to retrieve the version numbers from Apple, but their API is often error prone and provides challenges related to timed staging and geographic delays and availability issues. Due to severe rate-limiting by Apple any daily checks you run on MAS apps will be difficult, some of the more extensive checks will need to be distributed throughout the month. Probing Apple's official API is not even enough due to their bugs and limitations, you'll also need to implement support for probing their unofficial Web-API. There are special challenges related to Apple Arcade games and for the iPad apps that can be installed on ARM Macs. A general challenge related to the MAS APIs is that they contain only 'marketing' version numbers that often have no correlation to the version numbers that are actually stores in the app. The real version numbers aren't even available in their private Web-API. A special case is apps that had their latest version available in the store but are no longer available which need to be marked accordingly. Other stores for downloading apps and games apart from the MAS each provide distinct challenges. A common rule you want to obey is not to bug users by displaying minor updates that can only be obtained on a different store than where they bought something.

• Alternative Branches
Displaying the absolutely latest version of every app by default makes sense, but some vendors support multiple branches of their app in parallel. While this occurs around 2 orders-of-magnitude less frequently than users might believe it is still an important use-case. If a vendor still ships updates to a previous generation of an app, you should display the later generation by default but allow the user to specify that he'd prefer to see or apply updates to the older generation of that app instead. So, you'll need to track the latest version of each supported generation. The problem here is that the interaction of such a feature with all the other requirements (overrides, min-OS, etc) can get extremely complex.

• Updates & Upgrades
Many users are only interested in updating an app if it can be done without paying anything. So, you'll need to discern free 'updates' versus paid 'upgrades', which is difficult to do automatically. Some vendors charge again, even when the version number only changes marginally. Others have time-based licenses, which you need to implement custom support for to let the user know if the proposed update is free or not. Apart from cost there could be other reasons to mark some updates as major upgrades, like compatibility concerns or required upgrade procedures. Generally you'll want a framework that allows to display helpful information to the user under various circumstances like upgrade notes, compatibility issues, name/vendor changes, etc. Those messages need to be entered by the content team.

• Sparkle Feeds
A helpful fact for finding and applying updates is many popular macOS apps already use a framework called 'Sparkle' that implements the functionality to allow apps to update themselves. Sparkle-based apps provide the information about their latest version and the download URL in a standardized "appcast", making it seemingly easy to update them. There are numerous challenges: the appcast URL embedded in the app might be incorrect, no longer valid, or may not actually download the latest version of the app. Naive updaters (sorry 'Latest'...), only look at the appcast URL embedded in the app, and look for updates there. This works fine if the URL is actually embedded in the standard way (sometimes it isn't), and happens to be correct to obtain the latest version of the app. The likelihood of that working out decreases if the installed version of the app is older, especially since many vendors use different appcasts for different generations of their apps. So, what you need to do is to find out the correct appcast URL to use for each app and constantly maintain and update this mapping. If information about updates comes directly from the vendors you are especially vulnerable to the ubiquitous mistakes the vendors constantly make. You'll need to quickly eliminate appcasts if they have incorrect information (wrong bundle-version, switched bundle and short version, broken downloads, wrong pubdates, etc, etc) or refrain from directly using them at all. One could argue that support for Sparkle-based apps is easy but of little use since those apps can update themselves anyway. True, the ability to update apps that don't have any self-update functionality at all is more important. On the other hand, the percentage of apps that claim to have self-update functionality but where that actually doesn't work is suprisingly high, thats why you'll need to constantly evaluate all ~12.000 appcast URLs.

• Beta Versions & Staging
Especially with a crowd-sourced version-number database you'll have problems with pre-release versions of apps making it into your database. You only want to show stable official updates (unless a user selects an unstable 'alternative branch'). One approach is preventing beta versions from entering the database in the first place, e.g. you can only allow submissions for some apps if the version number is listed on some page of the vendor (in some format or transformed in some way). If the vendor does not list the version, the submission to the database is omitted. By preventing infrequent submission or validation instead of performing the check at frequent retrieval-time, a lot of CPU time can be saved. While this technique is effective at preventing beta versions showing up even if version-numbers are crowd-sourced, maintenance of the validation URLs and patterns is quite time-consuming. Another technique is to make the client ignore specific app versions retrieved from the database either individually ("marked as beta, to be ignored") or based on per-app-custom patterns ("this app marks beta releases in a specific way"). A simple but also effective technique is to just raise the minimum popularity requirements for database submissions to be considered as an update. Beta versions generally are less popular so it can make sense to only display updates if they have been installed by a specific minimum popularity threshold (which can be set and adjusted per-app).

• Websites & Release-Notes
Users expect to be able to quickly go to an app's homepage which is especially convenient for apps that cannot be updated. Homepage information for all apps can be a few megabytes so you may want to separate the info into homepages that update often or less frequently. Bonus points for tracking contact e-mail information for vendors. Even more importantly, a central part of an app updater is displaying the release-notes for the new app versions. Many users want to read the release-notes before updating an app to help decide whether they want to install the update or upgrade. Sparkle feeds most often contain release notes, but you also want to display release notes for other apps. We keep track of more than 2500 release-note URLs. Displaying those release notes and version histories can be tricky because of different display size requirements of those websites. Even after removing nasty things like cookie banners you'll want to decide for each release-notes URL whether it can be perfectly embedded with 'readability', without 'readability' or should not be embedded at all and instead presented to the user as a link he can open in his browser.

• Feeds and Finding Updates
A central part of your daily maintenance is going to be to find those updates and corresponding URLs every day. This is relatively easy for standardized appcasts (Sparkle, Squirrel), but more difficult in the general case. In many cases you want to track the version of an app that is offered for download on the vendor's download page. You'll want to implement an intelligent system so that using the download page can often work "automatically" to find updates even in unstructured sizes without having to provide a custom configuration (e.g. via REGEXPs) for every case. In many cases a per-source configuration will be required nevertheless. Also, one complication here is that dynamic websites often load download info on-the-fly so a normal URL fetch will not contain the info you are looking for (or plainly seeing when opening the URL in a browser). Scraping systems that evaluate the Javascripts can help in some cases, in other cases you need to sniff the actual source URL. Most apps have 2 (or even more) official versions, the latest download from the website and the latest version in their in-app version check. To determine the in-app update URL you'll need someone with good sniffing skills on your team. Ideally you'll add all info sources to your system and ditch any source that gets too far (in our case, 2 weeks) behind. Static download URLs are nice because they don't need constant apps and they can also be efficiently used to find new updates if the server supports delivering only the file size or the file date only. If the server does not support that, things get complicated and you cannot redownload all those apps every day. The danger of feed URLs (as well as static or semi-static) download URLs is that they might get stale, i.e. they are still online but actually outdated and new information or downloads are posted elsewhere. You'll need multiple mitigation strategies here, like automatically accessing URLs that have numbers by replacing those numbers with higher numbers and checking the results. Another essential but high-effort technique is comparing the versions you offer for download with the latest version number available in your database. If an app does not offer beta versions and your database has a higher version number than your download, you can infer that you missed an update. But because beta versions are so frequently submitted to the database, this technique can require a lot of manual supervision to check whether a specific new version really exists as an official update. More broadly, apps that have multiple "update channels" need to be considered on multiple levels. Also, a constant headache for your maintenance routine is falling into the blocking-trap. Things will get difficult you exceed some thresholds and your requests get blocked by the vendors or their middleware so you need to be prepared to split your requests onto multiple systems and IPs as well as employing spoofing techniques to have unsuspicious agents and referrers. Nevertheless you should strive to never put undue stress on the vendor servers, only download apps a single time and only if there has been an update and only access feeds once per day to make sure to stay on their good side.

• Downloading Updates
Downloading updates is normally a straightforward process but can be complicated by spiteful vendors that want to punish their users. Get ready to implement user-agent spoofing as well as referrer-spoofing to download some updates. Bonus points for handling cloudflare, captchas and differential updates.

• Extracting & Installing Apps
Extracting and installing app updates needs a few considerations. Most updates are delivered with common ZIP or DMG compression, but various more exotic formats should be supported. DMG decompression can be tricky due to bugs in Apple's "hdiutil" and task support causing freezes on some Macs. Most generally updates can be delivered as self-contained bundles, packages, installers or folders and each different type needs special handling. Finding the update is not entirely trivial in case the software type or extension changed (e.g. from screensaver to app). SSpecialhandling can be required if the app is contained in the download more than once, or if you want to skip an installer and directly extract an app from the installer resources, or if a download only contains the 'Contents' folder of an app-bundle. Packages (.pkg) require a lot of attention. The easiest way is to hand-off the installation to Apple's GUI Installer.app, but this will require the user to click through the installation, so you want to implement headless/automatic pkg installation too. One long-standing issue with packages is that many of them don't support renaming or removing an app and will install an additional app copy if the user has done so. For each downloadable package you should determine if that is the case, and what the default path of the installed components is so that you can warn the user if the package is going to install additional copies instead of updating the existing ones (or delete the old copies automatically). None of that can be done fully automatically (despite the "relocatable=…", "", "BundleIsRelocatable" tags...) because often package functionality is implemented in their pre- or post-installation scripts so your shell-scripting professionals need to dissect those scripts. The final consideration when installing an update is matching the existing permissions and owner information, dealing with the quarantine and preserving custom user info and settings like Finder icons and comments. Bonus points for prewarming GateKeeper so users can quickly launch updated apps.

• Displaying & Ignoring Apps
Scanning the whole harddisk for software-bundles is not a good approach as there will be hundreds of auxiliary apps in places like the 'Library', but just scanning /Applications and ~/Applications is not good enough either as you want to support non-app software types like screen-savers, drivers, preference-panes, plugins and many more too. Normally bundles in the Library folders should be ignored but in some cases software is only installed in weird places and you'll need to find them there too. Even when just considering the /Applications folder, many of the apps installed there should be ignored as they are auxiliary or helper apps that should not be tracked or even displayed because their names will not mean anything and just confuse users. Ignoring apps needs to be a flexible process that can be done either indirectly as a mass-ignore (e.g. based on bundle-id substrings) or directly by specifying bundle-identifiers to ignore. Mass-ignores will also need a mechanism for exceptions. For each ignored app you'll want to keep track of a ignore reason so that the users can learn exactly why an installed app is not displayed in the main app list. MacUpdater has around 60 mass-ignores and 8500 direct ignores to make sure the app list displayed to the user is always clean.

• Security
Security is essential and ignoring cyber security can ruin any business overnight. If your app-updater installs malware on your users Macs, you will most likely have to close shop. Even ignoring the financial aspect, it is your duty to keep your users safe and sound. That means: 1.) you want to warn the user if he has malware, adware, spyware installed. 2.) even regarding PuPs, you might want to warn the user and you definitely don't want to support updating those as dubious vendors often go from bad to worse and 3.) you want to implement a wide range of mechanisms to make sure that all downloaded updates are always legitimate and official and free of malicious code. Detecting malware (including PuPs) is a complicated business that can be a full-time occupation for a team in itself, but by deferring to others (like VirusTotal) as well as implementing custom algorithms to scan for common malware signatures you can make significant progress here with moderate effort. Our daily maintenance includes malware detection routines that has detected hundreds of malware variants significantly earlier than all AntiVirus engines supported by VirusTotal. MacUpdater marks over a 1000 apps as malware, adware or spyware and blocks all other software from vendors that have produced any of those. You want to keep track of the official code-signature team-identifier from all vendors and every downloaded update should get its identifier compared with the expected value. Additionally you might want to compare the team-identifier of the downloaded update with the installed app's identifier and compare the hash values of the download. Keeping track of the (ever-changing) official team-identifier of over 6000 apps is a huge undertaking also because the vendors don't publicize those identifiers. Nevertheless this work is essential to keep your users safe, because it is much easier for attackers to infiltrate a download server than to get hold of the private code-signing certificates of an vendor. Our meticulous tracking of code-signatures is the only thing that brought the stealth-overtake of a very popular Mac app to light in 2024. Note that code-signatures can be present and should be verified on apps (or bundles), PKGs and DMGs. Another part here is keeping your own infrastructure safe to make sure the config-file you deliver to your users is always safe and sound.

• Explanations
Most of the time updates are obvious - if CoolApp v1.2.3 is installed, it is likely that an update to version 1.2.4 is desired. But some situations are complicated and need an explanation both to be helpful to your users but also to protect against drowning in e-mails from confused users. You'll need mechanisms to detect complicated situations, add explanations for those situations both automatically and manually and present those explanations to the user. Situations that require explanation might include: the app has changed name, the app now has a lower version number than previously, the app needs special upgrade considerations or conditions, one of the app's "editions" or "variants" was replaced with another variant, the update is difficult to obtain or can only be updated in a specific way, etc. You'll also want a way to display explanations or "heads-up" notices only under some conditions, e.g. if the user has installed a version with known security problems. You should also keep track of whether apps (not supported for automatically updating them) can be updated directly in-app, via an updater app or only via the homepage as well as add explanations for why a specific app cannot be supported for automatic updating.

• Non-Apple App Stores
Apple's Mac App Store is not the only place where apps can be obtained indirectly (instead of directly from the vendor). Other stores exist specialized for games (like Steam or GoG) or apps (like SetApp). Each existing store needs special investigation and handling. Without going into detail, some stores cannot be supported so you should opt to ignore all apps installed via them. Other can be supported just fine, but as mentioned above you should refrain from asking users to "switch stores" or "switch into or out of a store" for minor updates.

• Adobe
No one could talk about updating apps without noting that 99% of the effort would not be required if app vendors would just follow the rules (from Apple) and would not constantly make mistakes. Every thing that could possibly go wrong, you'll see from multiple vendors all the time. And talking about vendors making mistakes is hard without also mentioning "Adobe". It seems Adobe has made Mac software for 40 years without actually having a single macOS engineer because nearly every mistake that can be made has been made and is still made by that vendor. 500 lines in our config file have to be dedicated to that vendor only because of everything they do wrong and which we have to work around. Shame on you Adobe for being so very technically incompetent and shame on you for not even providing a way to report all those bugs and bugs and bugs...


The 6000 words above only give a rough outline of the things and problems that need to be implemented, maintained and solved to achieve a competent app-updater for macOS and surely a few important topics have been forgotten. Thus is should be apparent that licensing/purchasing our technology is going to be cheaper than implementing something on your own even if most of your team is working for free.



BENEFIT

If you want to enter the app-update market, have a look at the "BENEFIT" section below that details what we've learned about this market in the past 7 years and to see what could be expected when selling (something like) MacUpdater. Tomorrow you could own that market!

Click here to expand the 'Benefit' chapter.



Our technology and systems are useful either if you want to offer an app-updater to end-users and companies (like we have done), or if you have a product (like an enterprise management system) that could be improved by incorporating our technology. In the second case you'll already know how much our technology could be worth to you and you can stop reading here. In the first case you'll need to evaluate about how much revenue can be made with an app-updater to see whether entering that market with our technology makes sense. Since we have been in that market for the past 7 years and have destroyed our only competitor along the way, we can share insights into the market and provide info about how much revenue MacUpdater can generate as-is or with some effort and changes.


• BASELINE SCENARIO
In the base scenario you don't need to do anything except convert the existing MacUpdater userbase to a subscription model. We cannot recommend staying on a non-subscription model as that has absolutely not worked out for us. MacUpdater has accumulated 30.000 paid customers. According to a recent poll, around half of the respondents would agree to a subscription model. If you combine the current userbase of 30.000 people with the subscription prices that people agree to (according to the poll), the yearly revenue of MacUpdater with a subscription model would be between 255k and 354k per year (depending on the price-tiering). Note that this scenario requires no marketing as you just need to convert the existing userbase and it can be expected that even people that claim they would not opt for a subscription could be persuaded, since MacUpdater is extremely addictive.
REVENUE ESTIMATE: 255.000€ - 354.000€ / year


• GROWTH SCENARIO
It is important to note that the current MacUpdater customer base of roughly 30.000 customers was built basically without any marketing effort. The annual marketing expenses for the past 7 years were considerably below 10.000€ per year. It is very likely that the userbase could be expanded drastically if some real effort would be put into marketing the product, having a website that isn't from the 90s, doing social media, etc. A presumably very conservative estimate would be that the userbase could be increased by a factor of 5 with some marketing effort:
REVENUE ESTIMATE: 1.500.000€ / year


• OPTIMAL SCENARIO
MacUpdater is an application that is basically useful to every Mac owner that has downloaded more than a handful of apps outside of the Mac App Store. Apple has sold around 125 million Macs in the past 5 years. If 25% of those Macs would have MacUpdater subscription at an average of 18€ / year, then this would be the best-case scenario for an app like MacUpdater in the consumer market. Calculating the resulting revenue is left as an exercise to the reader.


ENTERPRISE MARKET:
The above numbers refer to the consumer market only. We've largely ignored the corporate / enterprise / institutional market, though it is easy to see that this market would be much more interesting from a business standpoint. While keeping apps current is important for consumers, it is absolutely essential for businesses. A single exploited security flaw in outdated software can kill a business overnight. The size of the macOS enterprise security and device management market is around ~USD 10 BILLION per year! Keeping software current would be an essential part of that, but is something that is addressed only very poorly in existing solutions. Big players like Jamf and smaller players like Mosyle and Pareto have recognized the importance of software updates in their market, but their "solutions" are basically inacceptable: they only support a handful of apps and their updates are late. This market desperately needs MacUpdater's technology. The main question here is whether to enter the market directly (which needs serious additional development in support infrastructure like device update management consoles) or whether licensing the technology to existing companies like Jamf is preferred. Regarding licensing, the current revenue of Jamf is ~USD 500 MILLION / year and it is apparent that their solution would be a lot more attractive if it was actually able to reliably keeps Macs up-to-date.
Note that related to enterprise solutions MacUpdater already contains:
• A command-line app to update apps remotely or automatically that acts as a "remote control" to the full version of MacUpdater and various other settings and tools for enterprises.
• A solution for update-checking in extremely large and security-consciouses environments: App scanning takes place without network access in an efficient manner that scales up to hundreds-of-thousands of client Macs and the results are centrally evaluated. This solution is basically finished and can be deployed to enterprise client at any time
• An upcoming solution for a standalone command-line version of MacUpdater that can be used for completely remote and GUI-less updating. This version has been under development for some time and is 'mostly finished'. We expect it could be finished in one or two months.



CONCLUSION


Over the past 7 years we've built an elaborate system that near-perfectly solves the problems related to app-updating on the Mac. While the client app be improved further, the much more important maintenance and backend infrastructure is completely solid. Recreating such a solution would take years, as the there are many different problems related to tracking updates and app updating. While our attempts to sell one-time-purchases has been largely unsuccessful, we've built a fanatic userbase that can make MacUpdater quite profitable if converted to a subscription model. Doing some marketing could significantly increase the revenue with minimal effort and entering the business market could be even more profitable.

If you are interested in MacUpdater or its technology, just contact: root@corecode.io