If Hushfeed makes TikTok better for you, a coffee helps me keep testing patches and maintaining them as TikTok changes.
Hushfeed is a Morphe patch bundle for people who want TikTok to behave differently. It can cut feed clutter, guard risky taps, improve downloads and expose controls TikTok leaves buried or unavailable. Every selected patch is configured from one native settings screen inside the app.
Add Hushfeed to Morphe | Download the latest bundle | Tour the settings | Browse all 81 patches
Important
Hushfeed is very active in development, features and bugs are being actively pursued and improved! Hushfeed targets the global TikTok package, com.zhiliaoapp.musically, version 46.2.3. Use that exact APK when patching. See Supported target for the verified build details.
- Feed: Hide ads, Shop, livestreams, stories, photo posts, unwanted creators and videos matching your own rules.
- Touch controls: Add second-tap protection to Follow and Like. Share confirmation also covers accessibility actions and keyboard input. If Hushfeed cannot prepare the first confirmation, it stops that tap instead of sending and forgets any older confirmation. Turning it off immediately restores normal sending. Remap or disable long press and double tap.
- Playback: Choose speed and quality, stop loops, resume a video after scrolling or move to the next one automatically.
- Downloads: Save watermark-free video, original photos, separate audio and SRT subtitles with filenames and folders you control. The save button also works on videos whose creator turned downloading off.
- Comments and inbox: Filter comment text or accounts, translate comments and decide which Inbox rows appear.
- Privacy and diagnostics: Turn off supported telemetry, hide view and typing reports, back up settings and export a useful diagnostic report.
The block, local hide, sound and Not interested controls, rendered in a local UI test:
- Get the TikTok 46.2.3 APK. Google Play only offers the newest build, so take it from APKMirror.
- Use Morphe Manager 1.30.0 or newer. Manager refuses a bundle built against a patcher newer than its own, and this one is built against patcher 1.13.0, which Manager 1.30.0 was the first to ship. On anything older the bundle simply will not load.
- Add Hushfeed as a source in Morphe Manager. The quickest way is this link on the phone: Add Hushfeed to Morphe. Some in-app browsers block Android from handing a web link to another app. If Open in Morphe leaves you in the browser, open Morphe Manager, tap Sources, tap +, and paste
https://github.com/SysAdminDoc/hushfeed. You can also downloadpatches-0.36.0.mppfrom the latest release and load it as a local bundle. - Pick the patches you want and patch the APK. Keep the manager's existing signing key so TikTok stays logged in across updates. Every patch here fits the manager's 640 MB memory default except AMOLED dark theme, which rewrites TikTok's color resources and needs the limit raised to 768 MB. That 640 is the manager's default and not a measured minimum: the whole set apart from AMOLED fits in 576 MB. If patching stops with an out of memory error, that setting is the one to raise. A run that sits at 24 or 25 percent and never moves is the same problem wearing a different face: cancel it, set the limit to 768 MB and start again, and if that still stalls try 512 MB, which gives the patcher less to hold at once.
- Install the patched APK. From 2026-09-30, phones in Brazil, Indonesia, Singapore and Thailand ask for more before they will install an app from a developer Google has not verified. The flow is the same every time: turn on the option in Developer options, confirm the device lock, restart the phone, then wait 24 hours before the install goes through. After that it stays open for 7 days, or indefinitely if you chose that. This is not a one-off. Every Hushfeed release is an update, and an update goes through it again once the window closes.
adb installfrom a computer skips the whole thing. - Open TikTok, go to Settings and privacy, and tap Hushfeed. Every patch you selected has its switches there.
Selected patches activate when TikTok starts. The Settings patch adds the entry point and is selected by default. Deselect it and the other patches still apply, but their switches have nowhere to live. patches-bundle.json in the repository root is the source index Morphe reads for the published bundle.
| Patch | Description |
|---|---|
Automatic video advance |
Keeps TikTok's automatic advance enabled while preserving its pause, dialog and gesture checks, and shows TikTok's own Auto scroll action in the video panel for accounts outside its rollout. |
Foldable split comment view |
Shows comments beside the video on windows wider than a configurable threshold. Off by default. |
Subtitle tools |
Saves subtitle files beside downloaded videos and adds caption size, background, and clear-display options. |
Playback quality |
Selects the lowest, highest or a target video quality for playback, adaptive streams included. A second choice caps quality on mobile data and only ever lowers it. Download quality has its own setting. |
Advanced downloads |
Adds download quality choices, saves Photo Mode images directly from their source URLs, keeps a video's sound as its own audio file, and saves a profile picture or a story from a long press. |
Allow Duet and Stitch |
Ignores the creator's Duet and Stitch setting so the entries appear for videos that closed them. Everything else the app checks still applies: a photo post, a private video or one with music it may not reuse is still refused, and whether the upload is accepted is the server's decision, not the app's. |
Keep the screen's refresh rate |
Stops TikTok asking the screen to run slower than it can, which it does by asking for the frame rate of the video it is playing. On a 90 or 120 Hz phone that ask takes the whole app down to that rate, scrolling included. A request that is not slower than the screen is left alone. |
Hide the launcher shortcuts |
Empties the menu that opens on pressing and holding TikTok's icon on the home screen. The entries are built while the app runs rather than declared in it, and TikTok only rewrites them when it notices a difference, so this takes away what is already published and answers the handover that would publish more. Turning it off asks TikTok to build them again. Tapping the icon still opens the app, and a shortcut pinned to a home screen is left alone. |
Fit the video to the screen |
Puts the whole of a vertical video on screen instead of cropping it to the window. On a 9:16 phone nothing changes, because the video already fills it. On a Fold opened up, a squarer phone or a split view the sides or the ends stop being cut off. |
Notification controls |
Adds a switch for the notification saying somebody new followed you, and one for message streaks, neither of which TikTok lets you turn off. The follower switch drops the notification before Android is asked to post it, so nothing else in the drawer is affected. |
Long-press controls |
Lets a long press on a video keep TikTok's own action, do nothing, open the video's comments, save the original sound, or copy the link to the video or its sound, and can turn a press on the left or right third of the screen into a jump back or forward. Brings Double-tap controls with it, which supplies the comment control. |
Double-tap controls |
Lets double taps do nothing or open the current video's comments. |
Confirm feed interactions |
Adds optional second-tap protection to the feed Follow button and like heart. A red ring marks the armed button. |
AMOLED dark theme |
Replaces TikTok's dark background palette with black or a chosen color. The light theme keeps its colors. Choose this patch to enable it. It is the one patch that rewrites resources, so patching with it on needs the memory limit raised to 768 MB. |
Core Asset De-bloat |
Empties TikTok's bundled C2PA native libraries and Microblink payment-card OCR assets. Content credentials and card scanning may stop. Choose this patch to enable it. |
Instant Launch & Splash Blocker |
Stops TikTok's splash-ad preload tasks and returns false from its reviewed splash and TopView gates. Other startup behavior is left in place. Choose this patch to enable it. |
Language Pack Purger |
Empties unselected TikTok language bundles while always keeping English. Selected language codes are checked before any file changes. Choose this patch to enable it. |
Live Stream Suite Optimizer |
Empties TikTok's link-mic and LIVE match or minigame assets, then skips its gift-effect widget setup. Co-hosting, games and animated gifts may stop. Choose this patch to enable it. |
Network & Background Traffic Governor |
Turns off TikTok's buffer-preload gate and skips its push initialization task. Videos may start buffering later, and TikTok push notifications may stop. Choose this patch to enable it. |
Runtime Memory Governor |
Makes TikTok's reviewed Fresco animated-frame cache lookups return no cached frame. This can increase decoding work or change animation playback. Choose this patch to enable it. |
Studio & Creation De-bloat |
Empties TikTok's reviewed editor, camera-effect and face-model assets. Recording, editing, effects and creator tools may stop working. Choose this patch to enable it. |
Update Prompt Suppressor |
Skips TikTok's background and boot-finished device-ID update-check tasks. This may suppress some in-app update checks. Play Store updates are unaffected. Choose this patch to enable it. |
Always show publish date |
Always shows the publish date in video author information. |
Not interested button |
Adds a movable button that tells TikTok you aren't interested in the current video. It hides while comments are open. Off by default. |
Block author button |
Adds one-tap controls for blocking the uploader, hiding the uploader locally and blocking the current sound. The local-hide and sound controls have separate switches. Long press any visible control to move it, and all of them hide while comments are open. |
Comment tools |
Hides comments that contain chosen words or come from chosen accounts, turns the thumbs down on each comment into a block button, hides comment media and polls, and adds a box above the comments that narrows them by what they say or who said it. |
Copy comments without username |
Copies only the comment text without including the creator's username. |
Custom offline videos limit |
Adds a custom entry to TikTok's offline videos menu with a configurable limit from 1 to 1000 videos. |
Disable login requirement |
Removes TikTok's mandatory login gate from supported flows. |
Disable the long press quick share |
Keeps long-pressing Share from opening TikTok's quick-share interaction. |
Disable the long press repost |
Keeps holding Like from opening TikTok's repost action. |
Disable screen capture detection |
Prevents TikTok from reacting to screenshots and screen recordings. |
Allow screenshots and Circle to Search |
Removes secure window flags and disables the Circle to Search block. Off by default; restart after changing. |
Diagnostic tools |
Adds diagnostic logging, filtered reports and local TikTok crash capture. The switches are under Diagnostics in Hushfeed settings. |
Downloads |
Adds watermark-free downloads, comment sticker saving, configurable folders, and filename templates. It ignores the flag TikTok sets when a creator turns downloading off, so those videos save too. Network fetches accept public HTTPS addresses and follow at most five checked redirects. |
Show LIVE search |
Shows TikTok's search entry in the Live drawer where supported. |
Use non-personalized search |
Uses TikTok's non-personalized search mode instead of its saved account choice. |
Hide search suggestions |
Hides the suggested searches TikTok offers on the search page before you type, and stops the page asking for them. Your own search history is left alone. |
Feature Gate Lab |
Adds a menu for viewing and overriding supported TikTok feature flags and configuration values. |
Feature Gate Recorder |
Records feature gate reads while you use TikTok and compares them with their previous values. |
Follow diagnostics |
Reads what the server said about a follow. A follow TikTok turns down comes back looking like a success, so this reports the refusal and its reason once per session and, with diagnostic logging on, writes the whole exchange to the report. |
Comment publish diagnostics |
Says in the diagnostic report whether a comment send reached TikTok's publish code, what it had in hand, and whether it returned early or handed the comment to the request. A comment that never posts leaves no other trace. |
Feed filter |
Hides feed ads, including videos with creator commission disclosures, TikTok Shop items, livestreams, LIVE replays, stories, photo posts, paid partnerships, AI labelled videos, verified accounts, series, playlists, the playlist bar, the floating event badge and inserted cards. Videos can also be filtered by your own caption words, creator handles or patterns, sound names, length, the country they were posted from and their view, like, comment, favourite and share counts. Sponsored cards are dropped from the profile video viewer, the search grids and the Friends tab as well as the feed. |
Feed tab navigation |
Controls which loaded top and bottom navigation tabs remain visible, blocks newly added tabs when requested, and can hide the Tako AI bubble. |
Fix Google login |
Restores Google account sign-in after patching. |
Hide already seen videos |
Keeps a local record of the videos you have watched and drops them from later feed pages. The record never leaves the device and can be cleared from settings. |
Ghost mode |
Adds an option to stop TikTok reporting that you viewed a story or a profile or that you are typing. Online status is unchanged. |
Hide the risk control CAPTCHA |
Hides TikTok's risk control CAPTCHA dialog, raised by its BdTuring service, which the browsing CAPTCHA patch does not cover. Answers the Hide CAPTCHA popups setting, never touches SMS or two factor verification, and never hides a check the server raised over a follow, like, comment or repost. Off by default. |
Hide comment popup ads |
Stops the brand animation that plays over the comment sheet when a comment matches an advertiser's trigger word or emoji. |
Comment sort controls |
Shows TikTok's own comment sort sheet on every post, with its hot, newest, media and creator options, instead of the cut-down row an account outside the rollout is given. |
Enable voice comments |
Turns on TikTok's own voice comment recording and publishing entry points for accounts that do not have them. |
Hide CAPTCHA popups |
Adds a default-off setting to hide browsing and LIVE puzzle dialogs. Login and account verification stay visible, and so does any puzzle the server raised over a follow, like, comment or repost, because hiding one of those makes the action fail with no message. |
Hide floating promotions |
Removes floating promotional badges, coin icons, and timer banners from the Home feed. |
Hide video overlays |
Hides the visual search prompt TikTok lays over videos, the Live entrance in the top left corner, caption and music text, selected action buttons or their counts in the right column, survey cards and the status bar. |
Share sheet tools |
Asks twice before a video is sent to a friend from the share sheet. The check follows the account or conversation instead of the visible name and covers accessibility actions and keyboard input. It can also hide chosen people, share options or the whole Send to row. |
Hide feed LIVE button |
Adds an option to hide the LIVE button at the top left of video feeds. Shares its switch with the Live entrance option of Hide video overlays, and stops the button before it is built rather than hiding it once it is on screen. |
Hide feed follow button |
Adds an option to hide the + follow button below creator avatars in video feeds. |
Hide feed save button |
Adds an option to hide the save/favourites button from video feeds. |
Keep the Favorites tab |
Keeps the Favorites tab on your profile when TikTok's server puts the account into an experiment that empties it. Two people saw that after patching: the tab was there and the saved videos were not. |
Hide feed search button |
Adds an option to hide the search button at the top right of video feeds. |
Disable telemetry |
Adds an App behavior toggle that stops ByteDance AppLog analytics, AppsFlyer attribution, explicit Firebase screen reports and TikTok's Npth or MonitorCrash startup reporting. TikTok's own diagnostics go quiet with them. Off by default. |
Hide suggested accounts |
Stops the suggested accounts list from being built on the Activity, New followers and Inbox pages, and collapses every other People you may like card: the profile header, the Friends tab and the feed. Shares its switch with Hide inbox items. |
Hide inbox stories |
Hides the stories tray at the top of the Inbox and restores it immediately when the switch is turned off. Shares its switch with Hide inbox items. |
Expand activity list |
Adds an option to show the full Activity and New followers lists instead of collapsing them behind a View all button. |
Hide inbox items |
Adds a switch for each row and header control on the Inbox tab, so message requests, TikTok Tako, TikTok Shop, the stories tray and the rest can be hidden individually. |
Hide quick comment reactions |
Hides TikTok's exposed quick emoji row in supported comment inputs. |
Hold-and-slide 2x lock |
Enables TikTok's native hold, slide down, and release gesture to lock 2x speed. |
Open external links directly |
Opens profile and story website links in the system browser instead of TikTok's in-app browser. |
Playback speed |
Remembers playback speed or applies a default to each new video, with custom menu choices up to 3x. |
Remember clear display |
Remembers clear display between videos, or enters it automatically after a chosen delay. |
Resume videos after scrolling |
Continues supported videos from where playback stopped when returning after a scroll. |
Region spoof |
Matches locale, timezone and native region getters to the SIM preset, with a separate experimental store-region switch. |
SIM spoof |
Spoofs SIM country and operator information retrieved by TikTok, with country presets for easier setup. |
Sanitize sharing links |
Removes tracking parameters from TikTok links before they are shared, and can put a host of your choosing in place of tiktok.com. |
Settings |
Adds the Hushfeed settings screen to TikTok. |
Skip content warnings |
Adds an option to play videos TikTok has classified without the warning overlay asking to be tapped through first. |
Show author region |
Adds an option to show the country a video was posted from next to the creator's name on the feed. |
Show the progress bar |
Shows TikTok's native video seekbar where it would normally be hidden. |
Show the progress bar thumbnail |
Shows TikTok's video preview thumbnail while dragging the seekbar. |
Stop video looping |
Stops videos at the end instead of replaying them. |
Translate comments |
Adds comment translation controls using TikTok's translation system, with selectable language exclusions. |
The settings pages use grouped controls on an AMOLED background. Light mode follows TikTok's theme, including the space behind the system bars, and larger text wraps across lines without clipping headers, captions or editor labels. Changing font size or navigation mode keeps the settings page you were using and its Back history. If a page cannot finish loading, Hushfeed replaces partial controls with a translated explanation plus Back and Retry actions. Use Search settings at the top to find translated titles or descriptions and jump to the original control, including Feature Gate Lab. These screenshots come from native Android views rendered by the local test suite. Enabled controls and values are test fixtures.
Every settings page
| Page | Screenshot |
|---|---|
| Feed filter | View |
| Local creator list | View |
| Feed navigation | View |
| Interface | View |
| Comments and translation | View |
| Downloads | View |
| Playback | View |
| Inbox | View |
| Share sheet | View |
| Region settings | View |
| App behavior | View |
| Diagnostics | View |
| Settings search | View |
| Settings recovery | View |
| Feature Gate Lab | View |
| Gate details | View |
| Gate recording | View |
| Twice the text size | View |
| Twice the text size, light | View |
| Mirrored layout at twice the text size | View |
| Mirrored layout, light | View |
The native choice dialogs keep one indicator at the leading edge. These renders cover selected and unselected rows in both themes. The Included diagnostics images come from the shipped eight-choice picker with its real Apply and Cancel actions:
| Dialog | Dark | Light |
|---|---|---|
| Single choice | View | View |
| Included diagnostics | View | View |
Hushfeed saves what the app already has. The download reads the addresses TikTok itself fetched for the video you are watching, on the session you are already signed in with, so there is no separate request pretending to be a browser and nothing to keep in step with the site. That is the difference between this and a scraper. Through August 2026 yt-dlp had to rewrite its TikTok extractor twice and re-implement browser impersonation, and it broke again on 1 September. Cobalt has not shipped since April. None of that is a promise that saving always works. TikTok can change what it hands the app, and when it does the saver changes with the patches. It just means the thing most likely to break in a scraper is not part of how this works.
Select Subtitle tools in the patcher, then enable subtitle downloads in Downloads. Captioned videos and their SRT files share the same filename stem. Language names can use Unicode, and filename collisions keep separate tracks. Android 11 and later save the pair in Movies; Android 10 uses Download. The selected subfolder still applies. A failed subtitle transfer leaves the saved video intact and reports the partial result.
Caption appearance and the clear display option are in Interface:
The clear-display caption is removed as soon as you turn its switch off. Turning it back on restores the current cue when its video is still on screen.
Inbox category switches identify New followers, Activity, Archive, Tako and Shop from native row data. They work with translated labels. Turning a switch off restores an already loaded row on the next layout.
Playback has an optional default speed for every new video. A manual choice lasts until you change videos. To add 2.5x, enter it in Speed menu choices and restart TikTok; an empty list restores TikTok's menu.
Select Automatic video advance in the patcher, then enable Advance when a video ends in Playback and restart. The option re-enables native auto-scroll if TikTok turns it off, and it puts TikTok's own Auto scroll action in the video actions panel, which otherwise only appears for accounts in that rollout. Use the Playback switch to disable it.
Auto-advance session limit is zero by default. A positive value counts videos that finish while Hushfeed started scrolling, not prefetches or manual swipes. Recreating the feed or changing the limit starts a new count. Saving the same number, changing another setting or returning from the background keeps the existing count, including a reached limit. Hushfeed shows a brief notice when it stops.
Advanced downloads can send a sanitized TikTok link to another installed app. Enter its package name in Send links to another app; an empty value keeps TikTok's own save. The YTDLnis package is recognized explicitly as com.deniscerri.ytdl, so its documented audio or video type and optional background mode are available. The profile controls stay disabled for every other package, and an uninstalled target falls back to TikTok's save.
Photo filename templates can use {index}. TikTok's own Photo Mode saver numbers each image from 1 and starts over when the post has finished saving, including on Android versions that write straight to a shared folder.
Foldable controls are in App behavior. Settings save immediately, including when an older settings page is still open. A notification tells you when to restart TikTok.
Numeric feed limits show their actual unit with language-aware singular and plural labels.
Native settings pickers use one radio indicator for a single choice and one checkbox for multiple choices. The selected state remains accessible and is saved through Android's native list adapter.
Region spoof requires Override SIM details plus Match locale and timezone to country in Region settings. Each built-in country preset supplies a timezone. Country codes must be two ASCII letters. Locale scripts and extensions are retained, including when a legacy variant needs fallback handling. Restart TikTok after changing these settings. Enable the separate store-region option only if needed, since it can affect search. GPS and the network address stay unchanged. Neither switch can change where TikTok thinks you are on its own: your IP address, the history on your account and the language you read in all say the same thing they said before, and any one of them is enough for TikTok to keep serving the region it already chose.
Playback has two switches for a feed that keeps going when nobody is watching it. One takes the sound while a comment sheet is open and gives it back when the sheet closes. The other holds the feed after you return to the app until you tap once, and leaves the tab bar alone so messages, a profile and search stay one tap away. Both are off unless you turn them on. These two switches request audio focus; they don't call the native player pause used by the daily-budget hold.
Playback also carries a daily budget for the feed, on builds that include the block author patch, which is where the hook that knows which video is on screen comes from. It is off until you put a number in it, and until then nothing is counted at all. Set a video count, a number of minutes, or both, and Hushfeed says once that the day is used up. Set a hold too and the current player pauses behind a countdown for that many minutes, with a way through it on the countdown itself for the times you decide otherwise. It resumes only when the held video is still current, the feed is visible and audio focus permits playback. If another app holds focus past the countdown, Hushfeed waits for native focus to return before handing that video back. This also works when TikTok hasn't applied the queued pause yet. The panel follows the tab row as the screen layout changes. Messages, profiles and search are untouched, and so is the feed itself: nothing is dropped, so TikTok never refetches a batch it already sent. The day rolls over at four in the morning unless you move it, and the count and the hold both survive the app being killed. If a hold arriving out of nowhere is not what you want, there is a switch that fades the feed out over the last three quarters of a minute of a time budget, so you can see it coming. It needs a budget in minutes to follow and a hold to lead into, and it stays out of the way if you have turned system animations off.
Diagnostics includes Back up settings, Restore settings and Reset settings even without the logging patch. Backups include patch preferences and Feature Gate Lab rules with their enabled state. Choose a JSON file through Android's file picker. Invalid files leave settings unchanged. Restore and reset keep one undo copy inside TikTok. An interrupted write can recover from its backup file, and a current Hushfeed copy always wins over an older Metra copy. Export a backup first if you plan to clear app data or reinstall, since that removes the undo copy too. Restart after restoring or resetting. Show failures on screen decides whether a failure inside Hushfeed is also put in front of you while diagnostic logging is on. Turn it off and failures go to the report alone.
Backups record which settings they contain, so missing entries are rejected. A backup is a set of values to apply rather than a picture of the whole app, so anything it predates is left as you have it and the restore says how many that was. A backup from before the download destinations were split carries the one folder it knew about, and that fills in all three. If saving fails, recovery attempts both preference stores and keeps the undo copy available.
The Hook status row answers a question the patch list cannot. The patcher knows what it wrote into the APK, not whether a hook then found its anchor once TikTok was running, and TikTok renames things every release. When a hook loses its anchor the switch above it still reads on while nothing happens. Tap the row for a line per surface: how many lookups bound, how many did not, and the first thing that went missing. It hears from comments, comment translation, the inbox, the share sheet, the feed overlay, the bottom navigation and the story viewer, feed models, playback quality, sensitive warnings, CAPTCHA account state, external browser, sticker saves and story saves. The last four identify missing service calls, the sticker source adapters LLILLIZIL or X.0UD5, and the story chain LLJIJIL, LLJIJIL, LL, getAweme. "Everything found what it needed" means everything Hook status watches rather than every patch in the bundle. The same table goes into the exported diagnostic report, so it travels with a bug report.
The exported report also carries a feed filter table, and that one counts whether or not diagnostic logging is on. Several different routes can put a video on a profile page or in the feed, and a screenshot of an advert cannot say which one delivered it. The table gives a line per route: how many lists it was handed, how many videos were in them, how many it took out, and the last reason it gave. A route with no line has never run, which is the useful half, because a hook that never fired looks exactly like a filter that decided to keep everything.
Feature Gate Lab saves its master switch immediately. Its menu can reset overrides while the switch is off, reset all Lab data, or undo the last reset or import. Imported values stay disabled. The Lab holds up to 1,024 saved rules, and it rejects a save or import that would exceed that limit before anything changes. Reset all Lab data can recover an older oversized store without clearing other Hushfeed settings. Changes run in the background and report their result with a notification. Every filtered list in settings, the hidden creator editor, the share checklist and the Lab shows and announces its current result count. Removing a hidden creator says which entry was removed and moves focus to the next action. The recorder discards an interrupted session before taking the next baseline. Copied recorder reports use Android's sensitive-content flag on supported versions. Reports above 60,000 characters stay off the clipboard and use Save JSON. The undo copy stores Lab configuration privately; full-reset undo also restores captured observations during the same app run. Other patch preferences are unchanged.
Use JDK 21 or newer and an Android SDK configured through local.properties. GitHub Packages needs GITHUB_ACTOR and a GITHUB_TOKEN with read:packages access for the Morphe dependencies.
Run the runtime tests, then build the Morphe patch bundle and metadata:
./gradlew :extensions:tiktok:test
./gradlew :patches:generatePatchesList
pwsh -File scripts/validate-release-facts.ps1
./gradlew :patches:buildAndroidThe bundle is byte reproducible: two builds of the same commit produce the same file and the same SHA-256, so you can rebuild it yourself and check the published checksum against your own. The one field that would otherwise differ, the build timestamp in the bundle manifest, is pinned to the commit being built. Set SOURCE_DATE_EPOCH to override it. patches/build/bundle.sha256 is written from the finished bundle at the end of buildAndroid, so it always describes the file beside it.
Run these tasks in this order. The Android build finishes with verifyBundle, which checks the patch list and all three DEX payloads against the checksum recorded by the Android build. You can also run ./gradlew :patches:verifyBundle on its own to re-check the bundle this checkout built. It compares against a checksum only buildAndroid writes, so it will not verify a bundle from anywhere else.
The device-only patch and verification helpers read the signing password from HUSHFEED_SIDELOAD_KEYSTORE_PASSWORD. If it is unset, they use sideload, the password for the local test keystore. The helpers pass a response-file or environment reference to their child signing process, so the password value does not appear in that process's command line. patch-for-device.ps1 reads its package and version from patches-list.json. With -Replace, it removes TikTok only when the device returns an installed package path. A clean phone goes straight to installation, while a failed device query stops the script.
Each release ships a provenance receipt beside the .mpp, release-receipt-<version>.json. A checksum tells you a file arrived unaltered. It cannot tell you which APK the patches were proved against, which commit built the bundle, or what patching did to the Android manifest, and those are the facts that decide whether the bundle you downloaded is the one the release notes describe. The receipt records the tag, the full commit and its timestamp, the bundle's size, hash and manifest stamp, every extension payload's hash, and for each retained TikTok fixture: the APK's package, version and SHA-256, a verdict for every patch in the catalog, and the stock-to-patched difference in requested permissions and exported components.
scripts/build-release-receipt.ps1 writes it by actually patching each fixture with the Morphe desktop CLI, so the verdicts come out of the patcher's own report rather than from a claim. It refuses to run against a working tree with uncommitted changes: a bundle built from a dirty tree carries a wall-clock timestamp instead of the commit pin, and nobody could then rebuild it from the source the receipt names. validate-release-facts.ps1 checks the receipt on every run that has one and requires one for a release, and it refuses any manifest change that is not written down in scripts/manifest-delta-allowlist.txt. That list is empty on purpose. The patches change bytecode, not the manifest, and a release stops if that ever stops being true. An entry the patches no longer produce fails the run too, so the list cannot outlive the review it records.
verify-injected-registers.ps1 compares the patched APK with the exact 46.2.3 vendor fixture. The static half rejects an injected instruction outside its method's register count, a removed host method, or a removed DEX file. The optional device half requires the clean and patched Android verifier messages to match by text and count. Each device run removes its uploaded APK and generated ART files, including after a failed command. Reviewed removals must be exact method or dex entries in scripts/injected-register-removal-allowlist.txt; stale entries fail the run.
Gradle dependency verification is checked in at gradle/verification-metadata.xml. It records the reviewed release graph with SHA-256 checksums, so a changed cached artifact fails during dependency resolution. Every Bouncy Castle request in the build is rewritten to the reviewed 1.86 release, and two verification tasks check it: the TikTok extension tests check their own graph, and the patch tests check the build graph the Morphe patcher arrives on. Both read the request underneath the rewrite rather than the version it produced, so an unreviewed release stops the build instead of being quietly replaced. mavenLocal() is disabled by default, including the repository the Morphe settings plugin adds. Use -PallowMavenLocal=true only while developing a local plugin artifact, and leave it off for release builds. The wrapper distribution checksum in gradle/wrapper/gradle-wrapper.properties matches Gradle's published 9.7.1 binary.
To save offscreen screenshots, run ./gradlew :extensions:tiktok:test -PscreenshotDir=<absolute-directory>. The suite opens every settings section in dark and light themes, saves a value through the native picker, and exercises Lab search and overrides. A German fixture checks larger text at 360 dp width, and a Spanish one checks the same page at twice the text size on a 320 dp screen.
Worker-backed settings and Feature Gate Lab tests drain their owned executors before asserting, reset per-sandbox state before each case, and keep the region semantics check separate from the API ICU cross-check. These assertions do not depend on screenshot output or polling sleeps. Lab boundary tests reject malformed persisted scalars without replacing native values, keep imported rules disabled, clear runtime state across master and reset cycles, and hold recorder limits under concurrent calls. Translation batches expire before a visible fallback is retried, while SIM preset matching accepts missing values and keeps unsupported region fallbacks native.
Runtime tests cover feed marker and sound filters using both getter and field model shapes. Empty metadata and unrelated ids remain eligible; matching markers and sound phrases are rejected by their enabled filters. Shared resource lookup and global-layout ownership cover the feed, inbox and share hooks, with replacement, detach and failed-install fixtures for the host boundaries. A failed install also detaches the prior root before returning. Sticker publication tests keep collision protection on Android 9 and earlier. Native boundary tests cover structured numeric coercion and overflow, URL scheme refusal, destination roots, media fallback and frame bounds, plus direct navigation, share, LIVE, sound and translation policy shapes. Codec playback and final container behavior remain native-device checks. Deep feed tests cover all five count ranges through real responses, repeated response caching, late and final follow delivery, cached and offline fallback policy, hard-filter preservation and bounded probe rotation. The content fixtures reject swallowed runtime failures. Account-write challenge fixtures cover the supported follow, like, comment, repost and story routes found in TikTok 46.2.3. Follow tests drive all seven write routes through the refusal notice and verify that retained requests stop growing at the diagnostic limit. Direct and stream results consume their own request IDs; a skipped request can't reuse an earlier one. Diagnostic account pseudonyms use HMAC-SHA-256 with an installation key. Deliberately broken routes and readers must fail their regression tests. Video overlay traversals reuse their id, visibility and match buffers, so repeated layout passes do not rebuild the container lists. A synthetic 200-pass trace over 80 cells measured 57.68 ms before the change and 56.09 ms after it. Legacy settings import tests cover complete JSON and older text fragments, rejecting invalid values before any preference changes. Numeric tokens retain their precision until validation, and literal NUL characters cannot hide trailing data in imports or undo files.
The generated bundle is written to:
patches/build/libs/patches-<version>.mpp
Morphe reads patches-bundle.json from this repository, downloads the .mpp release asset listed there, and loads the patch metadata from that bundle.
After uploading the bundle and a SHA256SUMS.txt file to the GitHub release, verify the published asset against the local build:
pwsh -File scripts/validate-release-facts.ps1 -VerifyPublishedAsset -ArtifactPath patches/build/libs/patches-<version>.mppThe check follows the indexed URL, compares its SHA-256 with the local artifact, checks the matching entry in SHA256SUMS.txt, and counts the patches inside the published bundle against the number the index advertises.
That last one needs the Morphe desktop CLI. Set HUSHFEED_DESKTOP_JAR to the jar, or put morphe-desktop-<version>-all.jar under HUSHFEED_WORKDIR or build/morphe-tools, and it is found on its own. Without it the check stops rather than passing, because the count is the only part that reads what people actually download. The CLI wants a JDK 21 or newer, which is often not the java first on PATH: HUSHFEED_JAVA or JAVA_HOME says which one to use. When -Java names a directory, that directory must contain bin/java.exe or bin/java; an invalid explicit directory is reported instead of falling back to PATH.
The English text in the code is the key. Each language is one table under extensions/tiktok/src/main/l10n/, with the English on the left and the translation on the right. A language is kept in one of two forms, and the generator reads both. de.tsv is tab separated, one entry per line, # starting a comment. in.csv is the comma form Weblate hosts: a source,target header and a row per entry, quoting whatever needs it. Copy either one to <language code>.tsv or <language code>.csv, translate the right hand column, then run:
python scripts/gen-l10n.py
./gradlew :extensions:tiktok:testThe script writes two generated files, neither of them meant to be edited by hand. L10nTranslations.java is what the extension carries with its own code. en.csv is the list of source strings, which is the monolingual base a Weblate project points at, so a translator can work in Weblate and the export drops straight into l10n/ as <language code>.csv. The tests fail on any settings text that has no entry, on a language missing one, and on a table whose values are not the ones in the generated class, so both a gap and a stale run of the script show up before anything ships. Name the file with the code Android reports, which for the three languages that have two is the older one: in rather than id. The generator makes the table answer to both. The translations used to go into TikTok's own resources, but merging a few hundred strings into a table of 74,765 pushed patching past the memory Morphe Manager allows by default.
- App: TikTok, the global package
com.zhiliaoapp.musically - Version: 46.2.3, released 28 July 2026
- Build: version code 2024602030, arm64-v8a and armeabi-v7a, nodpi, minSdk 23
- SHA-256 of the APK every patch was verified against:
2fbe277a568e0e820cb51b09bcf0c0d788dc4fb070e66025f12d11cd3ec16936
Google Play only ever serves the newest build it thinks your device can run, so the copy on your phone is almost certainly not 46.2.3, and there is no way to ask Play for an older one. Take the APK from APKMirror, which serves the exact version, then patch that file rather than the installed app.
Every patch here is tied to code TikTok does not name: the classes and methods are renamed on each build, so a patch finds its place by the shape of the code around it. Those shapes move. 46.2.3 remains the declared target and the build with full device acceptance. The complete bundle also applies without a patch-time failure to retained 46.7.3 and 46.8.3 fixtures, but those outputs have not completed the same device behavior checks and are not advertised as compatible. Another build can fail loudly when an anchor moves or, worse, accept the wrong shape.
Only the global package is declared in the compatibility metadata.
The four resource optimizers are off by default. Before changing the APK, they compare the complete target set with reviewed paths and SHA-256 digests from the retained fixtures. An exact group that is already completely empty is accepted. A missing, extra, altered or partly emptied set stops patching. The 46.2.3 checks cover both its arm64-v8a and armeabi-v7a native libraries; the retained 46.7.3 and 46.8.3 fixtures contain only arm64-v8a libraries. Language packs also require the reviewed 64-directory and 207-file inventory, keep English, and preserve both Android aliases for Hebrew and Indonesian when either one is selected.
Hushfeed now contains the eight Kveld TikTok optimizers that were not already here. Kveld's Feed Ad Blocker behavior is covered by Feed filter, and its Npth startup coverage is part of Disable telemetry. Remove or disable Kveld's TikTok patches after updating Hushfeed. Keeping both current sources at their defaults activates all eight shared optimizer names because Kveld marks them on by default, even though the Hushfeed copies are optional.
| Bundle combination | Result on the reviewed 46.2.3 APK |
|---|---|
| Current Hushfeed source by itself | Supported. The eight optimizers stay off until selected. |
| Released Hushfeed 0.30.2 plus Kveld 1.23.1 | Migration-tested. Each Kveld TikTok root passed beside Hushfeed's 34 defaults. All 44 roots also passed in both source orders. |
| Current Hushfeed plus Kveld at defaults | Do not use this setup. Kveld's eight shared optimizers turn on automatically, and its separate feed and telemetry patches duplicate Hushfeed behavior. |
| Current Hushfeed plus Kveld with all ten Kveld TikTok roots disabled | The desktop CLI returns to the exact 34 Hushfeed defaults, but keeping the duplicate source provides no TikTok benefit. |
The migration matrix pinned Hushfeed 0.30.2 at 7645fb6dc8023ee445e623fa4ab83e9f76035916171fa00182a4e617a72101c4 and Kveld 1.23.1 at 28aa9a57c93b2e49482fd9b3f3bc359b0174c37ffb93cc9c5fc0155a8a65c7e1. Both full-order outputs had 26,072 entries and the same uncompressed entry-content SHA-256, 2a9a786e86ad356985e795a99b1ca4f97962c4dad20b43c8c58aa6d0d6e5ab3d. Neither order changed the 62 permissions, 648 named components or 66 exported components. Morphe desktop 1.15.0 applies an explicit duplicate name from the bundle supplied last, which is another reason to keep only one source for these patches.
Recorded one-at-a-time migration output hashes
These whole-file SHA-256 values identify the recorded 2026-09-13 runs. ZIP metadata can make a repeat produce a different whole-file hash, so the entry-content hash above is the stable full-order comparison.
| Kveld root beside Hushfeed defaults | Patched APK SHA-256 |
|---|---|
| Core Asset De-bloat | 849334dae2ec808ec75c718e382defa93608849d299abf07288c18e7886beb15 |
| Feed Ad Blocker | 54a70673b12e00519e022e3a2e541f116a62b7b1a952d34e49058833a94c6a4e |
| Instant Launch & Splash Blocker | 3f3cf431d3193ae21c828de5c7aa5f4fdfe3223c64eff8954138120161e95d6d |
| Language Pack Purger | 5495eb30a61eaf5897d491c70286ff552c2d8f5513b7c908c13e955329687fb1 |
| Live Stream Suite Optimizer | c9795096850a8d4ad719511372553bbaf2726714b5bf170007be30849ad5a6b2 |
| Network & Background Traffic Governor | cc12a76919de78573789914d8033d40cee064325e334c1db7658e17175473357 |
| Runtime Memory Governor | dd78aae02796a33ec510f077c91a7e2a3dc947a17b5bb9288f888679f5a1710d |
| Studio & Creation De-bloat | a0696fc12f49fc900b5eafdffd55992f09d1f0958e0ff5865180979d1eaff711 |
| Unified Telemetry & Tracker Silencer | a7b92689c1b31a71dee627ea1ff0a84b273995a3f4aa02af212aa7e6c6b477a2 |
| Update Prompt Suppressor | 56031325e755f9c4523ee4c6330d3515beb0e20a108e21d7026147d025689e9c |
patches/: Kotlin patch definitions, fingerprints and shared patch utilities.extensions/: Java extension code the patches inject into TikTok, with the Robolectric tests beside it.extensions/tiktok/src/main/l10n/: the settings translation tables.scripts/:gen-l10n.pygenerates translations,verify-all-patches.ps1checks every patch against a fixture,patch-for-device.ps1builds a signed APK for a named phone,measure-patch-heap.ps1checks selected memory limits, andvalidate-release-facts.ps1checks the public version, patch facts, indexed URL and published bundle hash.common.ps1holds the helpers the rest of them share: the work-directory path guard, the cleanup that will not delete outside it, the version read and the desktop CLI lookup.test-script-contracts.ps1covers all of those, the shared target reader and the guarded replacement step, which files a push runs which gate on, and that a released version keeps its changelog heading. It also checks that result reports can include declared patch dependencies without hiding a missing or unrelated patch.patches-list.json: generated patch metadata.patches-bundle.json: the Morphe source index for the published bundle.
Hushfeed stands on a lot of other people's work, and the licence asks that this stays visible.
- icysymmetra/tiktok-patches-for-morphe, the Metra patches this project was forked from. Most of the original patch set, the settings framework and the Feature Gate Lab come from there, as does the release history below 0.8.0 in the changelog.
- kveld9/kveld-morphe-patches for the eight optional TikTok optimizer patches and the extra Npth telemetry coverage, adapted from v1.23.1 at commit
fcb1768620b8f98a6dd31e801074589ce9a63356. - ReVanced, whose TikTok patches the whole lineage continues, and RookieEnough/De-Vanced, which upstream was built from.
- hxreborn/hxreborn-tiktok-patches for the inbox injectors, the telemetry patch, the risk control CAPTCHA hook and several feed card filters.
- BlueDragon4251/tiktok-patches-for-morphe for the seen video filter, the gate recorder and the download quality ideas.
- eduardo3677-ai/tiktok-patches-for-morphe for Ghost mode.
- @lyyako for the sanitize sharing links hook, the seekbar patch, the anti-recording patch,
Open external links directlyandAlways show publish date. - @oscski for
Disable the long press repost. - The Morphe team for the patcher, the manager and the patches template.
Files that came from another project keep their original notices, and files written here say so in their header. A test holds every source file the bundle ships to having one, so a file cannot arrive without saying where it came from.
The notices are also in the app, under Settings, About, Licenses, because Morphe asks that they reach the person using the software and not just the person reading the source.
- Hushfeed is not affiliated with TikTok, ByteDance or Morphe. "For Morphe" describes compatibility, nothing more.
- Patching a client TikTok didn't ship is your call. Some accounts see risk control puzzles or find that follows don't land on patched builds. Follow diagnostics says so when it happens, and the CAPTCHA hide never touches a puzzle raised over a follow, like, comment or repost.
- Everything Hushfeed adds runs inside TikTok, as TikTok. It has the permissions TikTok has and can reach the data TikTok can reach, so installing a patched build is the same trust decision as installing any app: you are trusting whoever produced the code. Read it before you run it. That is what the source is for.
- This repository and its GitHub releases are the only official source. Anything else offering a Hushfeed build, however similar the name or the site looks, was not made here.
- Bugs and ideas go in the issue tracker. Include the TikTok version, the patch involved, and what you expected.
GPLv3, inherited from the projects Hushfeed was built on. See LICENSE and NOTICE. The same notices are reachable on a patched phone under Settings, About, Licenses.











