How Magisk Handles Module Upgrades and the Update Mechanism
Magisk handles module upgrades by comparing versionCode values in module.prop, downloading updates via the updateCheck URL, and reinstalling through the install_module function while touching an update flag file to signal the Magisk app.
The topjohnwu/Magisk repository implements a robust, file-based upgrade system for Magisk modules that ensures safe updates without breaking existing installations. This mechanism relies on specific metadata files, shell-based installation scripts, and flag files to coordinate between the core Magisk framework and the companion Android app.
Understanding the Magisk Module Structure
Every Magisk module is a standard ZIP package containing a module.prop file at its root. This properties file defines the module's identity and upgrade behavior through several key fields:
id– A unique identifier used as the directory name under/data/adb/modules/version– Human-readable version stringversionCode– Integer used for deterministic version comparisonupdateCheck– Optional URL endpoint for fetching update metadata
When a module is installed, Magisk extracts this metadata to /data/adb/modules/<id>/module.prop, creating a persistent record that the upgrade mechanism references during version checks.
The Magisk Module Upgrade Workflow
The upgrade process follows a deterministic sequence that ensures atomic replacement of module files while preserving the module's identity and state.
Version Comparison and Detection
The Magisk app initiates upgrades by reading the installed /data/adb/modules/<id>/module.prop. It compares the local versionCode against the remote version available through the updateCheck URL or user-provided ZIP. If the remote versionCode is higher, the app marks the module as having an available upgrade.
Fetching Updates via updateCheck
Modules that declare an updateCheck URL in their module.prop enable automatic update detection. The Magisk app contacts this endpoint to retrieve update metadata or the newer ZIP file directly, storing the download temporarily before triggering the installation process.
The Re-installation Process
Magisk performs upgrades by re-running the install_module function defined in scripts/util_functions.sh. Because the module's id remains unchanged, the installer:
- Removes the existing directory at
/data/adb/modules/<id> - Extracts and writes the new module files to the same location
- Preserves module state files if necessary
This atomic replacement ensures no orphaned files remain from previous versions.
Signaling Upgrade Completion with the Update Flag
After a successful reinstall, the installer creates an empty file named update inside the module directory to signal the Magisk app. The relevant code in scripts/util_functions.sh handles this:
# scripts/util_functions.sh – install_module()
if $BOOTMODE; then
# Update info for Magisk app
mktouch /data/adb/modules/$MODID/update
fi
This flag file at /data/adb/modules/<id>/update persists until the Magisk app reads it and updates its UI, typically displaying an "Updated" badge or refreshing the module list to reflect the new version.
Manual Module Upgrades via CLI
Users can trigger upgrades manually without the Magisk app by using the command-line interface. The following command invokes the same install_module function used by the GUI:
# Download the newer module zip to device storage
# Then run the installer in boot mode
magisk --install-module /sdcard/NewMod.zip
This execution flow:
- Extracts
module.propto identify the module ID - Removes the old installation at
/data/adb/modules/<id> - Copies new files and touches the
updateflag - Cleans up temporary files upon completion
Post-Upgrade Hooks and Cleanup
After the core upgrade completes, Magisk executes several hook scripts that allow modules to perform migration tasks or restart services:
customize.sh– Runs during installation to handle custom extraction logic or version-specific migrationspost-fs-data.sh– Executes after the kernel mounts filesystems but before Zygote starts, allowing modules to adjust permissions or prepare data directoriesservice.sh– Runs late in the boot process when the system is fully operational, suitable for restarting daemons or applying runtime patches
The installer also cleans up stale state files such as remove or disable flags during the upgrade process, ensuring the module starts fresh with the new version while maintaining its enabled/disabled status as appropriate.
Key Source Files Implementing Module Upgrades
The upgrade mechanism spans both native shell scripts and Java components within the Magisk codebase:
| File | Role |
|---|---|
scripts/util_functions.sh – install_module() |
Core installer function that handles both fresh installs and upgrades; creates the update flag file. |
app/shared/src/main/java/com/topjohnwu/magisk/StubApk.java |
Provides update(Context) helper for app-side update coordination. |
app/stub/src/main/java/com/topjohnwu/magisk/DummyProvider.java |
Content provider stub that queries module state, including detection of the update flag file. |
docs/details.md |
Documents the upgrade flag behavior and UI expectations for module developers. |
Summary
- Magisk modules are upgraded by reinstalling the ZIP package while preserving the module ID, ensuring atomic replacement of files.
- The
install_modulefunction inscripts/util_functions.shhandles both initial installations and upgrades, removing old files at/data/adb/modules/<id>before extracting new content. - An empty
updateflag file is created at/data/adb/modules/<id>/updateto signal the Magisk app that an upgrade occurred. - Modules declare update endpoints via the
updateCheckfield inmodule.prop, enabling automatic version detection by comparingversionCodevalues. - Post-upgrade hooks including
customize.sh,post-fs-data.sh, andservice.shallow modules to execute migration logic and restart services.
Frequently Asked Questions
How does Magisk detect available module updates?
The Magisk app reads the installed module.prop from /data/adb/modules/<id>/module.prop and compares the local versionCode against the remote version fetched from the module's declared updateCheck URL. If the remote versionCode is higher, the app marks the module as having an update available.
What happens to old module files during an upgrade?
During an upgrade, the install_module function in scripts/util_functions.sh completely removes the existing directory at /data/adb/modules/<id> before extracting the new module files. This ensures no stale files remain from previous versions while preserving the module's identity through its consistent ID.
Can I upgrade Magisk modules without using the official app?
Yes, you can trigger manual upgrades via the command line using magisk --install-module /path/to/NewMod.zip. This command invokes the same install_module function used by the GUI, performing the version comparison, atomic replacement, and creation of the update flag file without requiring the Magisk app interface.
What is the purpose of the update flag file in Magisk modules?
The empty file located at /data/adb/modules/<id>/update serves as a persistent signal to the Magisk app that the module has just been upgraded. The app scans for this flag during startup to display "Updated" badges in the UI and trigger any necessary post-install hooks defined in the module's scripts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →