documentation.md

July 14, 2026 Β· View on GitHub

πŸ› οΈ Morphe Desktop Documentation

This is the complete documentation for Morphe Desktop. Morphe desktop offers both a GUI and a CLI. The GUI is how most people will use it, with a powerful CLI underneath for power users and automation. This documentation covers both, plus common workflows. If you’re brand new, start with the first-run guide, then come back here.

Now that you've done your first run, let's dig deeper into how the magic happens and how to make it even better.

πŸ“– Table of contents

🀝 Prerequisites

  1. Java Runtime Environment 21 or above (Azul Zulu JRE, Temurin or OpenJDK).
  2. Morphe Desktop jar file (morphe-desktop-*-all.jar). Download the latest from here.
  3. If using CLI: Patches mpp file (patches-*.mpp). Download the latest Morphe official patch files from here.
  4. If using CLI: Desired app file (app.apk or app.apkm). Download your apk from APK Mirror.
  5. [Optional] Android Debug Bridge (ADB) If you want to install the patched APK file to your device directly from your computer.

πŸ“‚ Where Morphe stores its files

Morphe keeps its runtime data: cached patch files, logs, scratch space for patching, and the default signing keystore in a single morphe-data/ folder. By default, this folder is created next to the JAR you run, so it survives upgrades and is easy to find. If that location isn't writable (e.g. running from an IDE, or from a read-only install path), Morphe falls back to ~/morphe/. The startup logs print which one is in use (look for Morphe data root: ...).

morphe-data/
  patches/         # cached .mpp patch bundles
  logs/            # application logs
  tmp/             # per-run patching scratch (the default --temporary-files-path location)
  morphe.keystore  # shared default signing key (see --keystore)
  config.json      # preferences + configured sources

Both the GUI and the CLI use this folder. In the GUI you can open it from Tools β†’ Open App Data. On the CLI, --temporary-files-path defaults to tmp/ (override it to send scratch elsewhere) and --keystore defaults to morphe.keystore here.

GUI

The GUI is the window you get when you double-click the jar and for most people, it's the way to use Morphe. No flags to memorize, no quoting mistakes, no terminal history full of 47 almost-right commands. Point, click and patch.

In your first run you used the GUI's Quick mode, the beginner-friendly path. Below we go deeper, focusing on Expert mode, where you can do much more.

The two modes

The GUI can run in one of two modes:

ModeWho it's forWhat you control
Quick (default)First-timers, fast patchesJust the APK: Morphe picks the patch source and the default patch set
ExpertRegular users, Power usersEverything: patch source & version, individual patches & their options, native-lib stripping, signing, and a live CLI-command preview

Quick mode home Expert mode home

On first launch you're in Quick mode. Switch anytime in Settings β†’ Expert mode β†’ Toggle ON. [Morphe will remember that.]

Expert mode toggle

Quick mode

Quick mode is the beginner path, covered step-by-step in the first-run guide: drop an APK, click Patch, watch it run, then install the patched app. Morphe chooses the patch source and the default patch set for you (by default). You can add additional sources here too. The rest of this section however focuses on Expert mode. That's where the GUI matches (and visualizes) everything the CLI can do.

Expert mode

Expert mode is a five-screen pipeline (for now): Home β†’ Patch source β†’ Patch selection β†’ Patching β†’ Result. Each screen below lists its controls (and the CLI flag it maps to, where there is one), then explains the details.

The TopBar

The home screen has a top bar (on the top):

Topbar

The sources pill sits in the center of the bar. It shows the loaded patches version and a N SOURCES count, with one small colored LED per source for the release channel it resolved to:

ControlWhat it does
Sources pill (center)The loaded patches version + a N SOURCES count with one colored LED per source – see below.
Device indicatorShows the connected ADB device (or "No devices connected"). Click to choose the target device for installs.
Tools (wrench)One-off actions + reference info – see Tools.
Settings (gear)All your preferences – see Settings.
LEDChannelMeaning
🟒STABLE LATESTnewest stable release – recommended
🟑STABLE OLDERa stable release, but a newer one exists
πŸ”΅DEV LATESTnewest pre-release (experimental)
πŸ”΄DEV OLDERa pre-release but behind

In Expert mode, click the pill to open the source manager – add, remove, refresh, or reorder sources (see Managing patch sources). In Quick mode it's informational. The same LED colors appear on each row inside the source manager.

The rest of the bar is the device indicator on the right (your ADB install target – more under Installing to a device), and the two icon buttons next to it: Tools (the wrench – logs, app data, clear cache, licenses; see Tools) and Settings (the gear – theme, modes, signing, strip libs, and more; see Settings).

1. Pick your APK

ControlWhat it doesCLI equivalent
Drag & drop /BROWSE FILESChoose the APK to patch (.apk, .apkm, .xapk, .apks)positional<apk> argument
SUPPORTED APPS listThe apps your patches target, each tagged with a recommended versioninformational – compare withlist-versions
CHANGE APKSwap the selected file–
CONTINUE / CONTINUE ANYWAYProceed to patch selection--force (when it reads ANYWAY)

Drop an APK anywhere on the window (the zone reads DROP APK HERE β†’ RELEASE TO DROP) or use BROWSE FILES. Split-APK bundles (.apkm / .xapk / .apks) are merged into a single APK automatically.

The SUPPORTED APPS list shows what the loaded patches can target, each with a version tag: STABLE LATEST, EXPERIMENTAL LATEST, ALSO STABLE, EXPERIMENTAL - so you know which APK version to download. Search it if it's long. A second tab, YOUR APPS, tracks everything you've already patched, see Your apps.

Supported Apps

Once an APK is dropped, Morphe reads its metadata (ANALYZING / "Reading app metadata…") and shows an info card with the app name, package, and version, plus CHANGE APK and CONTINUE.

Selected Apk

Tip

Each version tag in the SUPPORTED APPS list is a clickable shortcut. Click one to open that app's download page on APKMirror or other related sites. Grab the recommended version: matching versions means more patches apply.

Note

If your APK's version doesn't match what the patches expect, the button changes to CONTINUE ANYWAY. Proceeding is the GUI's equivalent of the CLI's --force. Incompatible patches are skipped, and the ones that do apply may or may not work. Newer-than-recommended versions are usually the riskiest.

Selected Apk with warning

2. Choose a patch source & version

ControlWhat it doesCLI equivalent
Release list (LATEST / STABLE / DEV / CACHED) + DOWNLOAD / SELECTPick and fetch a patch release-p <repo-url> (+ --prerelease for DEV)
PATCH NOTESRead a release's changelog-
LOCAL PATCH FILE β†’ BROWSEUse a.mpp already on disk-p <file.mpp>
EXPORT JSONSave anoptions.json for this bundleoptions-create / --options-file

Morphe fetches the available releases from your configured source and tags them: LATEST, STABLE, DEV (pre-release), and CACHED (already downloaded). Pick one and DOWNLOAD / SELECT it. Expand PATCH NOTES to read the changelog first. Already have a .mpp? LOCAL PATCH FILE β†’ BROWSE points straight at it.

Release Screen

Note

EXPORT JSON writes an options file describing every patch and its settings – the same artifact the CLI's options-create produces. Edit it and feed it back via --options-file for repeatable, scriptable runs.

Managing patch sources

The sources Morphe fetches from are configurable: add community sources (GitHub / GitLab repos, or morphe.software/add-source links), remove them, or refresh them. Adding more than one source is the GUI counterpart to passing several -p URLs on the CLI: their patches show up together, grouped by bundle, on the next screen.

Reordering. Drag a source by its handle to change its position in the list. Order is load priority – sources higher in the list are loaded first. This usually doesn't matter, but it can: if two sources ship a class with the same name (common when both are forks of the same patches project), the one loaded first wins. Keeping your primary source on top is the safe default.

Channel badge. Each enabled source shows a small badge for the release it resolved to, color-coded by release channel, the same colors (and meanings) as the sources-pill LEDs in The TopBar.

Sources sheet

3. Select patches

The full patch list from your selected bundle(s), with a running "N of M selected" count.

ControlWhat it doesCLI equivalent
Patch toggleEnable / disable a patch-e / -d (or --ei / --di)
SearchFilter the list–
Options editorEdit a patch's option values-O key=value
PATCH DEFAULTS / YOUR DEFAULTSWhether you've changed a patch's options–
Strip-libs summaryWhich native-lib architectures will be kept--striplibs (set in Settings)
Continue patching even if a patch failsKeep going when a patch errors instead of aborting the whole run--continue-on-error
COMMAND PREVIEW (COPY / EXPAND / COMPACT)The exact CLI command for your selections– (itis the CLI command)
PATCH (N)Start patching the N selected patchesruns thepatch command
  • Toggling & search: Flip patches on/off. Search filters the list (you'll see No patches match your search). If you added multiple sources, patches are grouped per bundle (No matches in this bundle when a filter empties one).

Patch Selection Screen

  • Options: Patches with configurable options show an options count. Click on this to expand and edit. Values are typed, see the Value Types Reference for how strings / booleans / lists are formatted. PATCH DEFAULTS means untouched. YOUR DEFAULTS means you've customized it. A few options are richer than a text box, notably custom icon option, which opens the Icon Studio instead.

Patch Selection Options

  • Strip libs: A summary chip shows whether native libs will be stripped (STRIPPING NATIVE LIBS / NO STRIPPING NEEDED / NO NATIVE LIBS). Change the kept architectures under Settings β†’ Strip Libs.
  • Continue patching even if a patch fails: By default a failed patch aborts the whole run. Enable this to skip the failure and apply the rest. The GUI's equivalent of the CLI's --continue-on-error.
  • Command preview: The exact CLI invocation your choices produce. COPY it to reproduce this run in a terminal or drop it into a script. EXPAND / COMPACT toggles full vs condensed.

Command Preview

Tip

The Command Preview is the best way to learn the CLI: configure a patch visually, copy the command, and you've got a reproducible one-liner. Handy for scripting or sharing exactly what you ran.

Custom app icons (Icon Studio)

Some patches can replace the app's launcher icon. When a patch exposes a custom icon option (for example the Custom branding patch on the official Morphe patches), its row in the options editor shows action buttons instead of a plain text field:

ControlWhat it does
DESIGN ICON / EDIT ICONOpen the Icon Studio to build a new icon (or re-open the one you saved)
IMPORT FOLDERPoint the option at an already-prepared icon folder. E.g. one exported from the Morphe Manager
DELETEClear the icon and delete its saved project + generated files

The patch expects a specific icon folder on disk, but you never have to build that by hand. The Icon Studio generates it and sets the option to its path. The row reads Custom icon ready once set, No custom icon set otherwise.

Custom icon option row

Foreground vs. background. Android adaptive icons are two layers: an opaque background and a foreground on top (the foreground may be transparent). The launcher masks the combined result into whatever shape the device uses. The Icon Studio mirrors this with two panels:

  • FOREGROUND: Your logo/mark, built from stacked layers. Each layer is an IMAGE, TEXT, or a SHAPE (circle, square, rounded, triangle, and more). Per layer you get TRANSFORM (move / scale / rotate, with RESET POSITION), color, and effects like SHADOW, GLOW, STROKE. Text layers add BOLD / ITALIC / UNDERLINE / STRIKE; DUPLICATE copies a layer.
  • BACKGROUND: A SOLID color, a GRADIENT (LINEAR / RADIAL / CONIC), or an IMAGE.

Important

Transparency is the #1 reason a custom icon looks wrong, and the two layers have opposite rules:

  • The foreground should be transparent around your mark. That cut-out is what makes the monochrome and notification icons read as a shape. A fully opaque foreground turns them into a solid block. If you import an opaque image the Studio warns you but won't auto-edit it (that could mangle a real icon). Fix it yourself with a transparent PNG, or use a TEXT / SHAPE layer instead.
  • The background must be opaque. Adaptive backgrounds can't be see-through. Here the Studio handles it for you. A transparent background image is automatically flattened onto a solid base, so backgrounds just work. (Although it is highly recommended to use a proper, fully opaque background.)

Colors come from a picker with saveable swatches, TEMPLATES give you starting points, and UNDO / REDO cover mistakes. Your work autosaves (the header shows SAVED), so EDIT ICON reopens exactly where you left off.

Live previews. The right side shows how the icon renders in three real contexts:

  • ADAPTIVE – the normal launcher icon (foreground over background).
  • MONOCHROME – the themed/monochrome icon (Android 13+): a tinted silhouette of the foreground.
  • NOTIFICATION / STATUS BAR – the small white silhouette used in the status bar and notifications, again derived from the foreground.

Because the monochrome and notification icons come from the foreground's shape and transparency, a background-only icon shows nothing in those two previews. That's expected, and the Studio points it out.

Note

PREVIEW SHAPES (circle, squircle, rounded, square) are only a preview of how different launchers might mask your icon. You don't pick the final shape. The device's launcher decides that, so your icon just needs to look right under any of them.

Hit SAVE ICON to export the folder and wire it into the option (CANCEL discards the current session), then patch as usual – the new icon is applied during patching.

Icon Studio

4. Patching

ControlWhat it doesCLI equivalent
Live log + N/total counterStreams progress(same output the CLI prints)
COPY ALLCopy the full log–
LOG FILE β†’ REVEAL / VIEWOpen the saved log on disk–
CANCELStop the run–

Morphe runs the pipeline and streams the same log lines the CLI prints, with a patched/total counter. The log is also saved to disk (morphe-data/logs/, reachable via Tools β†’ Open Logs). On failure you'll see PATCHING FAILED with the error in the log; on success, PATCHING COMPLETED – LOADING RESULT… advances to the result screen. CANCEL stops mid-run.

Patching Screen

Tip

If a patch fails, the saved log has the full stack trace: LOG FILE β†’ VIEW, or Tools β†’ Open Logs. It's exactly what to attach to a bug report.

Patching Screen Error

5. Result

ControlWhat it doesCLI equivalent
OUTPUT FILE / OPEN FOLDER β†’Locate the patched APKoutput path is set by-o / --out
ADB INSTALL (+ device picker)Install straight to a device-i / utility install
PATCH ANOTHERStart over with a new APK–
TEMPORARY FILES β†’ CLEAN UPFree this run's scratch spaceauto-purged by default; --disable-purge to keep
  • OUTPUT FILE / OPEN FOLDER β†’ – the finished APK and a button to reveal it in your file manager.
  • ADB INSTALL – with a device connected and ADB enabled, install directly. Pick a device (SELECT A DEVICE), wait for READY, install; you'll see INSTALLED ON <device> on success or RETRY on failure. Device states include UNAUTH (accept the USB-debugging prompt on the phone) and UNKNOWN. If ADB is off you'll see ENABLE ADB (turn on Auto-start ADB in Settings).
  • PATCH ANOTHER restarts the flow; TEMPORARY FILES β†’ CLEAN UP frees this run's scratch space (it shows how much).

Patching Screen Error

Note

ADB is optional. Without it, just grab the APK from the output folder and install it however you like.

After installing to a device, Morphe can make the patched app handle its supported web links, so those links open in the patched app instead of your browser or the stock app. It's ADB-only and fully reversible.

ControlWhat it doesCLI equivalent
OPEN LINKS WITH PATCHED APPRoute the app's supported web links to itutility install --route-links
Also stop <app> from opening these linksHand the stock app's links over too – only when a rename patch was used and the stock app is installed--disable-stock <stockPackage>

The LINK HANDLING section appears on the Result screen once the patched app is installed and a device is connected. On success, you'll see Links routed to patched app (or …, stock disabled); the change is reversible, restoring default link handling. To run it automatically after every ADB install, turn on Route links to patched app in Settings.

Link Handling toggle

Your apps

The home screen has two tabs: SUPPORTED APPS (what your patches can target) and YOUR APPS, a history of everything you've patched with Morphe. The "Your apps" tab carries a count badge, and when newer patches are available a banner ("N patched apps have updates available") jumps you there.

Your Apps section

Each entry is a card showing the app, the patched version, and when you patched it. Tap one for the full breakdown and actions:

ActionWhat it doesCLI equivalent
INSTALLInstall the patched APK to the connected device (showsINSTALL READY when the build is ready)utility install
UPDATERe-resolve patches and re-patch when a newer patch (or app version) is availablere-runpatch
RE-PATCHPatch the same app again with your saved settingsre-runpatch
UNINSTALLRemove the patched app from the connected deviceutility uninstall
FORGETRemove the entry from Your apps (history only – doesn't touch the device)–

The detail view also lists the app and Morphe versions and a per-source version breakdown, and flags when a newer patch may bump the app version.

Uninstall vs. Forget. Uninstall removes the app from your phone. Its dialog has an "Also remove from Your apps" checkbox to clear the history entry at the same time. Forget only drops the history entry and leaves the installed app untouched.

Note

When Morphe installs over ADB it records a non-Play installer source, so the Play Store won't silently update (and overwrite) your patched app. This is automatic, there's no setting for it.

Your Apps details dialog

Settings

The gear icon opens Settings – Morphe's persistent preferences. Think of it as the GUI's equivalent of the CLI flag set: most settings map directly to a patch flag.

SettingWhat it doesDefaultCLI equivalent
ThemeApp color scheme: Light, Dark, AMOLED, SystemSystem–
Expert modeSwitch between Quick and ExpertOff (Quick)–
Auto-cleanup temp filesDelete scratch files after patchingOnOn by default; --disable-purge to turn off
Auto-start ADBStart the ADB daemon on launch so devices are monitoredOffenables-i / install features
Update channelStable or Dev app updatesSmart (Dev on dev builds, else Stable)--prerelease (loosely)
Output folderDefault location for patched APKsThe input APK's folder-o / --out
SigningKeystore + credentials used to signSharedmorphe.keystore, alias Morphe, key password Morphe, store password empty--keystore, --keystore-password, --keystore-entry-alias, --keystore-entry-password
Strip LibsNative-lib architectures to keepKeep all--striplibs
Patched app runtime logsCapture logcat from a device after a patched app misbehaves––
Route links to patched appAfter an ADB install, auto-route the app's web links to it (with an optional "disable stock app's links")Offutility install --route-links

Settings dialog

A couple of toggles worth expanding on:

  • Auto-start ADB - when off, Morphe never starts the ADB server and all install/push features are disabled. Turn it on to install patched APKs to your phone from Morphe.
  • Update channel - Dev surfaces pre-releases; Stable only stable ones. If you've never chosen, Morphe defaults smartly (Dev when you're running a dev build).
  • Route links to patched app - when on, every ADB install is followed by routing the app's supported web links to the patched app (the Link handling step, run automatically). A nested Disable stock app's links option also stops the original app from opening those links – only relevant when a rename patch was used and the stock app is still installed. Both are reversible and need a connected device.

Signing

This is the GUI face of the --keystore* flags. Morphe signs every patched APK so it's installable; by default it uses a single shared keystore in its data folder (see Where Morphe stores its files) and reuses it across runs – Android only lets you update an installed app with an APK signed by the same key, so a stable keystore keeps re-patches installable over old builds.

ControlWhat it does
Keystore path +BROWSEPoint at your own keystore file
RESETRevert to Morphe's auto-generated default keystore
KEYSTORE PASSWORDPassword for the keystore file (default: empty)
KEY ALIASThe key entry's alias (default:Morphe)
KEY PASSWORDThe key entry's password (default:Morphe)
VERIFY CREDENTIALSCheck the keystore opens with the entered alias/passwords
GENERATE KEYSTORECreate a fresh keystore
EXPORTSave a copy of the keystore elsewhere

Keystore signing setting

Warning

If Morphe can't find the configured keystore it warns "Keystore not found – patching will fail until you restore it, pick another, or reset." Use RESET to fall back to the default, or BROWSE to a valid one.

Note

The signer only loads BKS keystores today. Support for pointing at PKCS12 (.p12 / .pfx) or JKS (.jks) keystores – auto-converted to BKS, original untouched – is coming in an upcoming release. (Same note as the CLI --keystore flag.)

Strip Libs

Choose which native-library architectures to keep in the patched APK; everything else is stripped, shrinking the file. This sets the default the Patch selection screen reports, and maps to the CLI's --striplibs.

ArchitectureUse it for
arm64-v8aARM 64-bit – most modern phones
armeabi-v7aARM 32-bit – older phones
x86_64Intel 64-bit – emulators / Chromebooks
x86Intel 32-bit – legacy emulators

Strip-libs setting

Warning

Only strip architectures your device doesn't use. If you keep just arm64-v8a and install on a 32-bit device (or the wrong emulator), the app won't run. When unsure, keep your phone's architecture (almost always arm64-v8a).

Patched app runtime logs

A debugging aid: capture logcat from a connected device after a patched app crashes or misbehaves, to attach to a bug report. CLEAR DEVICE LOGS wipes logcat before you reproduce the issue; SAVE DEVICE LOGS then pulls the filtered output to a file. Both require a connected, ADB-authorized device.

Logcat Logs

Tools

The wrench icon opens Tools – one-off actions and reference info, kept out of Settings so a destructive action doesn't sit next to your preferences.

ActionWhat it does
OPEN LOGSOpen the logs folder (morphe-data/logs/)
OPEN APP DATAOpen Morphe's data folder – themorphe-data/ directory (see Where Morphe stores its files)
CLEAR CACHEDelete downloaded patches and logs (they re-download as needed)
VIEW LICENSESBrowse the open-source licenses of Morphe's dependencies
VersionThe running app version is shown at the bottom

Tools Setting

Note

CLEAR CACHE asks for confirmation, then removes downloaded .mpp files and logs from morphe-data/. Nothing irreversible, patches re-download on the next run.

VIEW LICENSES opens a searchable browser of the open-source licenses for every third-party library Morphe bundles. Use the search box to filter by name – handy for license compliance, or just to see what's under the hood.

Licenses browser

Installing to a device (ADB)

Morphe can push patched APKs straight to your phone over ADB:

  1. Enable Auto-start ADB in Settings (off by default).
  2. Connect your phone via USB with USB debugging enabled, and accept the authorization prompt on the device.
  3. The device indicator in the top bar shows it; click to pick a device if several are connected.
  4. After patching, use ADB INSTALL on the Result screen.

Device Indicator

Device states you may see: READY (good to go), UNAUTH (accept the USB-debugging prompt on the phone), UNKNOWN (reconnect / check the cable), and No devices connected.

Note

ADB is entirely optional: it only powers install-to-device. You can always patch without it and install the output APK manually.

CLI

Prefer the terminal, or automating Morphe in a script or CI? The CLI exposes everything the GUI does – if you just want to patch an app, the GUI above is the easier path.

The CLI suite is an extremely powerful tool. It has some general flags but is mainly divided into 5 main sub-commands (and they all lived in harmony, until the fire nation attacked. Caught that reference?):

img.png

General flags

-h, --help:

Shows all the general flags and sub commands available.

java -jar morphe-desktop-*-all.jar --help

-V, --version:

Shows the current version of the morphe-desktop.jar

java -jar morphe-desktop-*-all.jar --version

Subcommand 1: patch

This is the most fundamental sub-command. Add the patch keyword to run this sub-command.

java -jar morphe-desktop-*-all.jar patch [flag/s]

Here is a quick lookup for all the flags under this subcommand:

FlagDescription
-p, --patchesPaths to .mpp files or GitHub or GitLab repo URLs (repeatable, one per bundle)
--prereleaseFetch latest dev pre-release instead of stable release
(positional arg)APK file to patch
-o, --outPath to save the patched APK to
-e, --enableEnable a patch by name
--eiEnable a patch by index
-d, --disableDisable a patch by name
--diDisable a patch by index
-O, --optionsSet patch option values (e.g.-Okey=value)
--exclusiveDisable all patches except explicitly enabled ones
-f, --forceSkip APK version compatibility check
-i, --installInstall to ADB device (optional serial)
--mountInstall by mounting over existing app (requires root)
--keystorePath to keystore file for signing
--keystore-passwordKeystore password
--keystore-entry-aliasAlias of the key pair in the keystore
--keystore-entry-passwordPassword for the keystore entry
--signerSigner name in the APK signature
--unsignedSkip signing the final APK
-t, --temporary-files-pathPath to store temp files
--disable-purgeKeep this run's scratch files (deleted after patching by default)
--striplibsArchitectures to keep, comma-separated (e.g.arm64-v8a,x86)
--bytecode-modeBytecode mode:FULL, STRIP_SAFE, or STRIP_FAST
--verify-with-sdkVerify the patched DEX/APK using an Android SDK
--continue-on-errorContinue patching if a patch fails
--options-filePath to options JSON file
--options-updateAuto-update options JSON file after patching
-r, --result-filePath to save patching result JSON

Note

The examples used for each flag below only show the usage of that specific flag, but in practice, you'll almost always combine multiple flags together to customize your patching. Here's an example of a more complete command:

java -jar morphe-desktop-*-all.jar patch -p patches.mpp -o your_app_patched.apk --striplibs arm64-v8a --force --continue-on-error -d "change package name" -d "spoof signature" "your_app.apk"

-p, --patches:

Required: Yes

Default: -

This flag specifies the patch file(s) to apply to your APK. You can pass local .mpp file paths or a GitHub or GitLab repository URL, and you can repeat -p to combine several bundles in one run (see Using multiple patch bundles below). When a URL is provided, Morphe automatically downloads the .mpp file from the latest release and caches it for future runs.

java -jar morphe-desktop-*-all.jar patch --patches patches-*.mpp your_app.apk

You can also pass a GitHub or GitLab repo URL:

java -jar morphe-desktop-*-all.jar patch --patches https://github.com/MorpheApp/morphe-patches your_app.apk
java -jar morphe-desktop-*-all.jar patch --patches https://gitlab.com/MorpheApp/morphe-patches your_app.apk

Or a specific release URL:

java -jar morphe-desktop-*-all.jar patch --patches https://github.com/MorpheApp/morphe-patches/releases/tag/v1.0.0 your_app.apk
Using multiple patch bundles

-p can be repeated to combine several .mpp bundles in a single run:

java -jar morphe-desktop-*-all.jar patch -p patches-a.mpp -p patches-b.mpp your_app.apk

The name-based selection flags (-e, -d, -O) apply to the bundle they follow. Each -p starts a new bundle, and the selections after it belong to that bundle until the next -p:

java -jar morphe-desktop-*-all.jar patch -p patches-a.mpp -e "A patch from bundle A" -p patches-b.mpp -d "A patch from bundle B" your_app.apk

Index-based selections (--ei/--di) are the exception. Their numbers refer to the combined list across all supplied bundles, not a single one. Run list-patches with the same set of -p files to see the combined numbering:

java -jar morphe-desktop-*-all.jar list-patches -p patches-a.mpp -p patches-b.mpp

Then enable/disable by those combined indices. The index points to a patch no matter which bundle it came from, so its position relative to each -p doesn't matter:

java -jar morphe-desktop-*-all.jar patch -p patches-a.mpp -p patches-b.mpp --ei 57 --di 12 your_app.apk

--prerelease:

Required: No

Default: false

When using a GitHub or GitLab repo URL with --patches, fetch the latest dev pre-release instead of the latest stable release.

java -jar morphe-desktop-*-all.jar patch --patches https://github.com/MorpheApp/morphe-patches --prerelease your_app.apk

Positional argument (APK file):

Required: Yes

Default: -

The APK file you want to patch. This is passed directly without a flag name, at the end of the command.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp your_app.apk

Note

Morphe also supports .apkm, .xapk, and .apks files (split APK bundles). If you pass one of these, Morphe will automatically merge the splits into a single APK before patching.

-o, --out:

Required: No

Default: a subfolder named after the app, created next to the input APK – <app>/<app>-Morphe-<appVersion>-patches-<patchesVersion>.apk

Specify a custom output path for the patched APK.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp -o /path/to/output.apk your_app.apk

-e, --enable:

Required: No

Default: -

Enable a specific patch by its exact name. Can be used multiple times to enable several patches.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp -e "Patch name" -e "Another patch" your_app.apk

--ei:

Required: No

Default: -

Enable a specific patch by its index number. Can be used multiple times. Use list-patches to find the index of each patch.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --ei 1 --ei 5 your_app.apk

-d, --disable:

Required: No

Default: -

Disable a specific patch by its exact name. Can be used multiple times.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp -d "Patch name" your_app.apk

--di:

Required: No

Default: -

Disable a specific patch by its index number. Can be used multiple times. Use list-patches to find the index of each patch.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --di 456 your_app.apk

Tip

You can combine -e, -d, --ei, --di and --exclusive in the same command.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --exclusive -e "Patch name" --ei 123 your_app.apk

-O, --options:

Required: No

Default: -

Set option values for patches. Options are key-value pairs passed alongside patch enable flags. To set a value to null, omit the value.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp -e "Patch name" -Okey1=value1 -Okey2=value2 your_app.apk

To set an option to null:

java -jar morphe-desktop-*-all.jar patch -p patches.mpp -e "Patch name" -Okey1 your_app.apk

Warning

Option values are typed. Setting a value with the wrong type can cause the patch to fail. Use list-patches --with-options to see the expected types.

Common types: string, true/false, 123 (integer), 1.0 (double), [item1,item2] (list)

--exclusive:

Required: No

Default: false

Disable all patches except the ones you explicitly enable with -e or --ei. Useful when you only want a specific set of patches applied.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --exclusive -e "Patch name" your_app.apk

-f, --force:

Required: No

Default: false

Skip the APK version compatibility check. By default, Morphe will warn you and skip patches that aren't compatible with your APK's version. This flag forces all compatible patches to run regardless.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --force your_app.apk

Tip

Patches are built for specific app versions. If you're using versions that are newer or older than the recommended ones, Morphe will skip all the incompatible patches (which is almost all of them since the version don't match) by default. Use --force to apply them anyway - they may still work fine, especially on recent versions.

-i, --install:

Required: No

Default: -

Automatically install the patched APK to a connected ADB device after patching.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp -i your_app.apk

If no serial is provided, it installs to the first connected device. You can optionally specify a device serial.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp -i SERIAL123 your_app.apk

Tip

Make sure ADB is working before using this flag:

adb shell exit

--mount:

Required: No

Default: false

Install the patched APK by mounting it on top of the original app. Requires root access and the original app to be installed on the device.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp -i --mount your_app.apk

Note

Make sure you have root permissions:

adb shell su -c exit

--keystore:

Required: No

Default: the shared morphe-data/morphe.keystore (see Where Morphe stores its files)

Path to a keystore file containing a private key and certificate pair to sign the patched APK with. If not specified, Morphe uses a single shared keystore in its data folder – auto-creating it on the first run and reusing it afterwards. Reusing one keystore is intentional: Android only lets you update an installed app with an APK signed by the same key, so a stable keystore means you can re-patch and reinstall over a previous build.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --keystore /path/to/keystore.bks your_app.apk

Note

The patcher signs using BKS keystores. If you point --keystore at a PKCS12 (.p12/.pfx) or JKS (.jks) file, Morphe auto-detects the format from the file's contents (not its extension) and converts a BKS copy to sign with. Your original keystore file is never modified.

--keystore-password:

Required: No

Default: empty (no password)

Password to open the keystore file itself. Different from the key entry password (--keystore-entry-password). Morphe's auto-generated default keystore has an empty store password, so you typically only need this flag when supplying your own keystore that was created with one.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --keystore keystore.jks --keystore-password "mypassword" your_app.apk

Note

The CLI and the Morphe Manager Android app share the same keystore defaults (alias "Morphe", password "Morphe"), so a keystore generated by either tool works in the other without extra flags.

--keystore-entry-alias:

Required: No

Default: "Morphe"

The alias of the private key entry inside the keystore.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --keystore keystore.jks --keystore-entry-alias "my-alias" your_app.apk

--keystore-entry-password:

Required: No

Default: "Morphe"

Password for the specific keystore entry.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --keystore keystore.jks --keystore-entry-password "mypassword" your_app.apk

--signer:

Required: No

Default: "Morphe"

The name of the signer embedded in the APK signature.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --signer "My Signer" your_app.apk

--unsigned:

Required: No

Default: false

Skip signing the patched APK entirely. The output APK will not be signed and cannot be installed directly on a device without signing it separately.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --unsigned your_app.apk

-t, --temporary-files-path:

Required: No

Default: morphe-data/tmp/ next to the JAR (falls back to ~/morphe/tmp/)

Path to a directory where Morphe stores temporary files during patching.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp -t /tmp/morphe-temp your_app.apk

--disable-purge:

Required: No

Default: false

By default, this run's scratch files are deleted once patching finishes. Pass this flag to keep them instead β€” useful for debugging a failed patch. Does not affect cached patches, other sessions, or config.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --disable-purge your_app.apk

--striplibs:

Required: No

Default: -

Comma-separated list of native library architectures to keep. All other architectures will be stripped from the APK, reducing file size.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --striplibs arm64-v8a,armeabi-v7a your_app.apk

--bytecode-mode:

Required: No

Default: STRIP_FAST

Controls how Morphe processes the APK's bytecode (DEX) during patching. Trade-off between speed, output size, and safety.

ValueDescription
FULLRebuilds and includes all bytecode. Largest output, slowest, safest - use if you hit runtime issues with the stripped modes.
STRIP_SAFEStrips bytecode that is provably unused, while keeping anything reachable via reflection or dynamic loading.
STRIP_FASTDefault. Aggressively strips unused bytecode for the smallest, fastest build. May break apps that rely on reflection.
java -jar morphe-desktop-*-all.jar patch -p patches.mpp --bytecode-mode FULL your_app.apk

Tip

If a patched app crashes at startup or has odd missing-class errors, switch to STRIP_SAFE or FULL and see if it fixes things.

Note

On Windows, Morphe currently forces bytecode mode to FULL regardless of what you pass to this flag (workaround for a platform-specific issue). The flag still works as expected on macOS and Linux.

--verify-with-sdk:

Required: No

Default: - (verification is skipped)

Verify the patched DEX and APK files using a local Android SDK after patching. Helpful for catching corrupt output before installing on a device. Pass a path to your SDK install directory, or pass the flag with no value to let Morphe auto-discover one.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --verify-with-sdk /path/to/android-sdk your_app.apk
java -jar morphe-desktop-*-all.jar patch -p patches.mpp --verify-with-sdk your_app.apk

Note

When you pass --verify-with-sdk without a path, Morphe resolves the SDK in this order:

  1. $ANDROID_HOME
  2. $ANDROID_SDK_ROOT
  3. OS-default install location:
    • macOS: ~/Library/Android/sdk
    • Windows: ~/AppData/Local/Android/Sdk
    • Linux: ~/Android/Sdk

If none of those resolve to a real SDK, Morphe errors out with a hint to either set one of the env vars or supply a path explicitly.

--continue-on-error:

Required: No

Default: false

By default, patching stops on the first patch failure. This flag lets Morphe continue applying the remaining patches even if one fails.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --continue-on-error your_app.apk

--options-file:

Required: No

Default: -

Path to a JSON file that controls which patches are enabled/disabled and their option values. Generate one using the options-create subcommand.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --options-file options.json your_app.apk

Note

If the file you specify doesn't exist yet, Morphe will automatically generate one with default values at that path and use it for the current patch. This means you can skip options-create entirely - just pass a path to a non-existent file and Morphe will create it for you.

Tip

The options file is great for repeatable patching. Generate it once (either with options-create or by letting --options-file auto-generate it), tweak it, and reuse it every time you patch.

--options-update:

Required: No

Default: false

Automatically update the options JSON file after patching to reflect the current patches. Without this flag, the file is left unchanged. New patches get added, removed patches get cleaned up.

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --options-file options.json --options-update your_app.apk

-r, --result-file:

Required: No

Default: -

Path to save a JSON file containing the patching result. The file records:

  • the package name and version of the patched app
  • whether patching succeeded overall
  • the result of each patching step
  • the list of applied patches
  • the list of failed patches, with their error details
java -jar morphe-desktop-*-all.jar patch -p patches.mpp -r result.json your_app.apk

Subcommand 2: list-patches

Lists all available patches from the supplied MPP files. Useful for finding patch names, indices, compatible packages, and options before patching.

java -jar morphe-desktop-*-all.jar list-patches --patches patches.mpp [flag/s]

Here is a quick lookup for all the flags under this subcommand:

FlagDescription
--patchesPaths to .mpp files or GitHub or GitLab repo URLs
--prereleaseFetch latest dev pre-release instead of stable release
--outWrite patch list to a file instead of stdout
-d, --with-descriptionsShow patch descriptions
-p, --with-packagesShow compatible packages
-v, --with-versionsShow compatible versions
-o, --with-optionsShow patch options
-u, --with-universal-patchesInclude patches compatible with any app
-i, --indexShow patch index
-f, --filter-package-nameFilter patches by package name
-x, --include-experimentalInclude experimental app versions in the output

--patches:

Required: Yes

Default: -

One or more paths to .mpp patch files or GitHub or GitLab repository URLs to list patches from. When a URL is provided, Morphe downloads the .mpp file and caches it for future runs.

java -jar morphe-desktop-*-all.jar list-patches --patches patches.mpp
java -jar morphe-desktop-*-all.jar list-patches --patches https://github.com/MorpheApp/morphe-patches

--prerelease:

Required: No

Default: false

When using a GitHub or GitLab repo URL with --patches, fetch the latest dev pre-release instead of the latest stable release.

java -jar morphe-desktop-*-all.jar list-patches --patches https://github.com/MorpheApp/morphe-patches --prerelease

--out:

Required: No

Default: -

Write the patch list to a file instead of printing to stdout. Useful in environments where > redirection is not available.

java -jar morphe-desktop-*-all.jar list-patches --patches patches.mpp --out patches-list.txt

-d, --with-descriptions:

Required: No

Default: true

Show the description of each patch. Enabled by default - use --with-descriptions=false to hide them.

java -jar morphe-desktop-*-all.jar list-patches --patches patches.mpp --with-descriptions=false

-p, --with-packages:

Required: No

Default: false

Show the packages each patch is compatible with.

java -jar morphe-desktop-*-all.jar list-patches --patches patches.mpp --with-packages

-v, --with-versions:

Required: No

Default: false

Show the compatible app versions for each patch. Requires --with-packages to be useful.

java -jar morphe-desktop-*-all.jar list-patches --patches patches.mpp --with-packages --with-versions

-o, --with-options:

Required: No

Default: false

Show the configurable options for each patch, including their keys, types, default values, and possible values.

java -jar morphe-desktop-*-all.jar list-patches --patches patches.mpp --with-options

-u, --with-universal-patches:

Required: No

Default: true

Include patches that are compatible with any app (universal patches). Use --with-universal-patches=false to only show patches targeting specific packages.

java -jar morphe-desktop-*-all.jar list-patches --patches patches.mpp --with-universal-patches=false

-i, --index:

Required: No

Default: true

Show the index of each patch. The index can be used with --ei and --di in the patch subcommand.

java -jar morphe-desktop-*-all.jar list-patches --patches patches.mpp

-f, --filter-package-name:

Required: No

Default: -

Only show patches that are compatible with the specified package name.

java -jar morphe-desktop-*-all.jar list-patches --patches patches.mpp --filter-package-name com.google.android.youtube

-x, --include-experimental:

Required: No

Default: false

By default, only stable app versions are listed. Pass this flag to also include experimental versions.

java -jar morphe-desktop-*-all.jar list-patches --patches patches.mpp --include-experimental

Subcommand 3: list-versions

Lists the most common compatible app versions for the patches in the supplied MPP files. Useful for knowing which APK version to download before patching.

java -jar morphe-desktop-*-all.jar list-versions --patches patches.mpp [flag/s]

Here is a quick lookup for all the flags under this subcommand:

FlagDescription
--patchesPaths to .mpp files or GitHub or GitLab repo URLs
--prereleaseFetch latest dev pre-release instead of stable release
-f, --filter-package-namesFilter by package names
-u, --count-unused-patchesInclude unused patches in the version count
-x, --include-experimentalInclude experimental app versions in the output

--patches:

Required: Yes

Default: -

One or more paths to .mpp patch files or GitHub or GitLab repository URLs. When a URL is provided, Morphe downloads the .mpp file and caches it for future runs.

java -jar morphe-desktop-*-all.jar list-versions --patches patches.mpp
java -jar morphe-desktop-*-all.jar list-versions --patches https://github.com/MorpheApp/morphe-patches

--prerelease:

Required: No

Default: false

When using a GitHub or GitLab repo URL with --patches, fetch the latest dev pre-release instead of the latest stable release.

java -jar morphe-desktop-*-all.jar list-versions --patches https://github.com/MorpheApp/morphe-patches --prerelease

-f, --filter-package-names:

Required: No

Default: -

Only show versions for the specified package names. Can be used to check versions for a specific app.

java -jar morphe-desktop-*-all.jar list-versions --patches patches.mpp -f com.google.android.youtube

-u, --count-unused-patches:

Required: No

Default: false

Include patches that are not enabled by default when calculating the most common compatible versions. By default, only patches that are enabled are counted.

java -jar morphe-desktop-*-all.jar list-versions --patches patches.mpp --count-unused-patches

-x, --include-experimental:

Required: No

Default: false

By default, only stable app versions are counted and shown. Pass this flag to also include experimental versions.

java -jar morphe-desktop-*-all.jar list-versions --patches patches.mpp --include-experimental

Subcommand 4: options-create

Creates or updates an options JSON file for controlling which patches are enabled/disabled and their option values. The generated file can be passed to the patch subcommand with --options-file.

java -jar morphe-desktop-*-all.jar options-create [flag/s]

Here is a quick lookup for all the flags under this subcommand:

FlagDescription
-p, --patchesPaths to .mpp files or GitHub or GitLab repo URLs
--prereleaseFetch latest dev pre-release instead of stable release
-o, --outPath to the output JSON file
-f, --filter-package-nameFilter patches by package name

-p, --patches:

Required: Yes

Default: -

One or more paths to .mpp patch files or GitHub or GitLab repository URLs to generate options from. When a URL is provided, Morphe downloads the .mpp file and caches it for future runs.

java -jar morphe-desktop-*-all.jar options-create -p patches.mpp -o options.json
java -jar morphe-desktop-*-all.jar options-create -p https://github.com/MorpheApp/morphe-patches -o options.json

--prerelease:

Required: No

Default: false

When using a GitHub or GitLab repo URL with --patches, fetch the latest dev pre-release instead of the latest stable release.

java -jar morphe-desktop-*-all.jar options-create -p https://github.com/MorpheApp/morphe-patches --prerelease -o options.json

-o, --out:

Required: Yes

Default: -

Path to the output JSON file. If the file already exists, Morphe will merge the current patches into it - preserving your existing settings, adding new patches, and removing patches that no longer exist.

java -jar morphe-desktop-*-all.jar options-create -p patches.mpp -o options.json

Tip

Run this command again after updating your .mpp file to keep your options file in sync. Existing settings are preserved.

-f, --filter-package-name:

Required: No

Default: -

Only include patches compatible with the specified package name in the generated options file.

java -jar morphe-desktop-*-all.jar options-create -p patches.mpp -o options.json -f com.google.android.youtube

Options JSON Workflow

The options JSON file lets you save your patch preferences and reuse them across multiple patching sessions. Here's the typical workflow:

Step 1: Generate the options file

Use options-create to generate a JSON file with all available patches and their default settings:

java -jar morphe-desktop-*-all.jar options-create -p patches.mpp -o options.json

Step 2: Edit the file

Open options.json in any text editor. You can enable/disable patches and set option values. The file contains a list of patch bundles, each with patch entries that look like:

{
  "patchName": {
    "enabled": true,
    "options": {
      "optionKey": "optionValue"
    }
  }
}

Set "enabled": false to disable a patch, or change option values as needed.

Step 3: Patch using the options file

Pass your customized options file to the patch command:

java -jar morphe-desktop-*-all.jar patch -p patches.mpp --options-file options.json your_app.apk

Step 4: Keep the file in sync (optional)

When you update your .mpp file to a newer version, patches may be added or removed. You have two ways to sync:

  • Re-run options-create - this merges new patches in while preserving your existing settings:

    java -jar morphe-desktop-*-all.jar options-create -p patches.mpp -o options.json
    
  • Use --options-update during patching - this auto-updates the file after patching:

    java -jar morphe-desktop-*-all.jar patch -p patches.mpp --options-file options.json --options-update your_app.apk
    

Note

CLI flags (-e, -d, --ei, --di, -O) always take precedence over the options file. If you enable a patch via CLI that the options file disables, the CLI wins. Morphe will log when this happens.

Tip

You can also skip options-create entirely. If you pass --options-file with a path that doesn't exist yet, Morphe will auto-generate the file with defaults for you.


Subcommand 5: utility

Parent command for utility operations. It allows for things like manually installing or uninstalling apps via ADB, clearing the cache directory, etc. Has three sub-subcommands: install, uninstall, and clear-cache.

utility install

Manually install an APK file to one or more ADB-connected devices.

java -jar morphe-desktop-*-all.jar utility install [flag/s] [device-serial...]
FlagDescription
-a, --apkAPK file to install
-m, --mountMount over an existing app (requires package name and root)
--route-linksAfter installing, route the app's supported web links to it ("open with")
--disable-stockWith--route-links: also stop the named stock package from handling them
(positional arg)ADB device serial(s)
-a, --apk:

Required: Yes

Default: -

Path to the APK file you want to install.

java -jar morphe-desktop-*-all.jar utility install -a patched_app.apk
-m, --mount:

Required: No

Default: -

Mount the APK on top of an existing app instead of a regular install. Pass the package name of the app to mount over. Requires root access.

java -jar morphe-desktop-*-all.jar utility install -a patched_app.apk -m com.google.android.youtube

Required: No

Default: -

After installing, route the app's supported web links to it ("open with"), so they open in the patched app instead of the browser or the stock app. The package name is read from the APK, so no value is needed.

java -jar morphe-desktop-*-all.jar utility install -a patched_app.apk --route-links
--disable-stock:

Required: No

Default: -

Use with --route-links. Also stops the named stock package from handling those links – needed when a rename patch was applied and the original app is still installed.

java -jar morphe-desktop-*-all.jar utility install -a patched_youtube.apk --route-links --disable-stock com.google.android.youtube
Positional argument (device serials):

Required: No

Default: First connected device

One or more ADB device serials to install to. If not provided, installs to the first connected device.

java -jar morphe-desktop-*-all.jar utility install -a patched_app.apk SERIAL1 SERIAL2

utility uninstall

Manually uninstall a patched app from one or more ADB-connected devices.

java -jar morphe-desktop-*-all.jar utility uninstall [flag/s] [device-serial...]
FlagDescription
-p, --package-namePackage name of the app to uninstall
-u, --unmountUnmount instead of uninstall
(positional arg)ADB device serial(s)
-p, --package-name:

Required: Yes

Default: -

The package name of the app to uninstall.

java -jar morphe-desktop-*-all.jar utility uninstall -p com.google.android.youtube
-u, --unmount:

Required: No

Default: false

If the app was installed by mounting (using --mount), use this flag to unmount it instead of a regular uninstall.

java -jar morphe-desktop-*-all.jar utility uninstall -p com.google.android.youtube --unmount
Positional argument (device serials):

Required: No

Default: First connected device

One or more ADB device serials to uninstall from. If not provided, uninstalls from the first connected device.

java -jar morphe-desktop-*-all.jar utility uninstall -p com.google.android.youtube SERIAL1 SERIAL2

utility clear-cache

Delete Morphe's cached data: downloaded patch files, logs, and temporary files. By default it prints a short confirmation message.

java -jar morphe-desktop-*-all.jar utility clear-cache [flag/s]
FlagDescription
--infoShow a per-category breakdown of what was cleared and the space freed
--info:

Required: No

Default: false

Show how much was cleared from each location (patches, logs, temp) with file counts and the total space freed, instead of just a confirmation line.

java -jar morphe-desktop-*-all.jar utility clear-cache --info

Value Types Reference

When setting patch options with -O or in an options JSON file, values are typed. Using the wrong type can cause a patch to fail. Here are the supported types and how to format them:

TypeExampleNotes
StringstringPlain text
Booleantrue, false
Integer123Whole numbers
Double1.0Decimal numbers
Float1.0fDecimal withf suffix
Long1234567890, 1LLarge numbers, optionalL suffix
List[item1,item2,item3]Comma-separated, no spaces
List (mixed types)[item1,123,true,1.0]Items are parsed by their type
Empty list (any type)[]
Typed empty listint[]Empty list of a specific type
Nested empty list[int[]]
List with null/empty[null,'','"]

Escaping:

Quotes and commas inside strings need to be escaped with \:

  • \" - escaped double quote
  • \' - escaped single quote
  • \, - escaped comma (treated as part of the string, not a list separator)

List items are parsed recursively, so escaping works inside lists too:

What you wantHow to write it
Integer as a string[\'123\']
Boolean as a string[\'true\']
List as a string[\'[item1,item2]\']
Null as a string[\'null\']

Example command:

java -jar morphe-desktop-*-all.jar patch -p patches.mpp -e "Patch name" -OstringKey=\'1\' your_app.apk

This sets stringKey to the string "1" instead of the integer 1.

πŸ”¨οΈ Building

Want to build Morphe Desktop from source instead of grabbing a release? Here's how.

Requirements: Java Development Kit 17 (e.g. Azul Zulu or OpenJDK).

  1. Clone the repository:

    git clone git@github.com:MorpheApp/morphe-desktop.git
    cd morphe-desktop
    
  2. Build it:

    ./gradlew build
    

Note

If the build fails with an authentication error, you need to authenticate to GitHub Packages. Create a personal access token with the read:packages scope here, then add it to ~/.gradle/gradle.properties:

gpr.user = your-github-username
gpr.key = your-token

When the build finishes, the runnable JAR is at build/libs/morphe-desktop-<version>-all.jar.