What HarmonyX is and how Unity developers can detect it
Learn what HarmonyX is, how BepInEx and MelonLoader use it to patch Unity methods, and how to detect it.
By Tim UhlottFounder|Last updated: August 9, 2026|14 minutes read
unityanti cheatharmonyx
If you have read about BepInEx or MelonLoader, you have probably also seen HarmonyX mentioned right next to them. HarmonyX is not another mod loader. It is the patching library that many mods use after a loader has already put their code into your game.You will learn what HarmonyX is, how mod loaders and frameworks use it, and what it technically does inside a Unity process.
What HarmonyX is
HarmonyX is a runtime method patching library for .NET code. In the Unity world, that usually means it can change how your C# methods behave while the game is already running.It is a BepInEx maintained fork of the original Harmony project (often called Lib.Harmony). Most Unity modding docs simply say "Harmony," but BepInEx and MelonLoader commonly ship HarmonyX specifically.A useful way to place it in the stack:
BepInEx or MelonLoader are the frameworks and loaders. They get into the process and load mods.
The mod or plugin is the actual cheat or feature code.
HarmonyX is the library that mod uses to rewrite game methods.
So HarmonyX is a tool used by frameworks and by the mods those frameworks load. It is not the host that starts the modding session.
How mod loaders and frameworks use HarmonyX
Tools like BepInEx and MelonLoader include HarmonyX, so plugin authors do not have to ship their own patcher.The usual flow for a mod using HarmonyX looks like this:
The loader boots into the Unity process.
The loader finds and loads plugin or mod DLLs.
A plugin creates a Harmony instance, often with a unique ID.
The plugin calls something like PatchAll() to apply its patch classes.
From that moment, selected game methods run through the patched path.
That is why people sometimes think HarmonyX "is BepInEx." BepInEx makes HarmonyX easy to use, but HarmonyX can also work outside BepInEx if some other host loads the assembly first.In practice, a mod uses HarmonyX when it wants to do things like:
Run code before a method starts
Run code after a method finishes
Change parameters or return values
Skip the original method completely
Rewrite parts of the method's IL for more advanced changes
For legitimate mods, that might mean better UI, accessibility options, or content hooks. For cheats, that might mean forcing return true on a purchase check, skipping cooldowns, or rewriting damage and inventory logic.
How HarmonyX works technically
HarmonyX does not edit your source code and it does not need to permanently rewrite your shipped DLLs on disk. It patches methods at runtime.At a high level, HarmonyX:
Finds the target method through reflection.
Collects your prefix, postfix, transpiler, or finalizer patches.
Builds a new combined method that includes those patches.
Redirects the original method to that new implementation.
After that redirect, every call to the original method goes through the patched version instead.
Prefixes
A prefix runs before the original method. It can inspect or change inputs. It can also return false to skip the original method body. That is one of the simplest cheat patterns: patch a validation method with a prefix that returns early and pretends everything is valid.
Postfixes
A postfix runs after the original method. It can read or replace the result. A common pattern is "let the game calculate the value, then overwrite the return with something better for the cheater."
Transpilers
A transpiler edits the Intermediate Language (IL) of the method before the patched version is created. This is more advanced. Instead of only wrapping the method, the mod can change individual instructions inside it.
Why this is powerful in Unity
Unity gameplay code is full of normal methods: take damage, spend currency, unlock item, check entitlement, start cooldown, submit score. If those methods exist on the client and the client is allowed to decide the result, HarmonyX gives a mod a clean way to intercept them.On Mono games, this is especially direct because the managed methods are easier to target. On IL2CPP games, the loader and interop layer still let many mods reach equivalent method targets, so HarmonyX style patching remains relevant there too.
A tiny example
[HarmonyPatch(typeof(PlayerWallet),nameof(PlayerWallet.SpendCoins))]classSpendCoinsPatch{// Runs before SpendCoinsstaticboolPrefix(int amount){// Skip the original method completelyreturnfalse;}}
In a real cheat, that kind of patch can stop coin spending, force free unlocks, or combine with a postfix that changes balances. The important part for developers is not this exact sample. The important part is the model: once HarmonyX is active, your methods are no longer guaranteed to run as compiled.
Why Unity developers should care
If you develop a single player game, you will mostly not care about mods or cheats. Maybe you even appreciate the extra content and longer lifecycle other players create. A user bought the game or app and can modify it to their advantage. No one gets hurt.But what if someone does get hurt? That usually means financial loss for you as the developer, or a broken experience for your players. No one wants a speeding or wallhacking opponent in a multiplayer game. And no one wants a player sitting on top of a competitive leaderboard without actually being the best.Financially, that can mean skipping licence checks, skipping ads, or unlocking items and features they should not have.The attacker does not need to reverse every system. They only need the right method name and a loader that can host the patch.So how can you protect your game? Let's start by looking at the clues HarmonyX leaves.
Traces HarmonyX leaves
HarmonyX is quieter than a full mod loader tree, but it still leaves clues:
Managed assemblies such as HarmonyX or 0Harmony loaded into the process
Known Harmony types and patch registries present at runtime
Methods that suddenly have detours or wrappers they did not have at build time
Loader folders nearby, because HarmonyX patches usually arrive through BepInEx or MelonLoader
In Unity games, HarmonyX plus an unofficial loader is a very common modding and cheating pattern. It is a pattern that can be detected and blocked.
Detecting HarmonyX traces
The traces from the prior chapter are a good starting point. You can check for them in your game and decide what to do next: warn, restrict online features, or block startup.
Loader folders nearby, because HarmonyX patches usually arrive through BepInEx or MelonLoader.
HarmonyX rarely shows up alone. It usually arrives with a loader, and that loader leaves folders and files next to your game install.BepInEx often looks like this:
BepInEx/
BepInEx/core/
BepInEx/plugins/
BepInEx/config/
BepInEx/patchers/
doorstop_config.ini
MelonLoader is a bit more mixed, and can include things like:
MelonLoader/
Mods/
Plugins/
UserData/
UserLibs/
version.dll, winhttp.dll, or dobby.dll
A simple first check is to look for those loader folders when your game starts. If they are present, you can treat that as a strong signal and block the session.
voidAwake(){if(Directory.Exists("BepInEx")|| Directory.Exists("MelonLoader")){ Debug.Log("Mod loader detected. Blocking game from starting.");}}
Managed assemblies such as HarmonyX or 0Harmony loaded into the process
HarmonyX is loaded into the process as a managed assembly. The common assembly names are 0Harmony and sometimes HarmonyX. That is the DLL name, not a C# type name. You can detect it by scanning the assemblies already loaded into the current AppDomain.
voidAwake(){bool harmonyLoaded = AppDomain.CurrentDomain.GetAssemblies().Any(a =>{string name = a.GetName().Name;return name =="0Harmony"|| name =="HarmonyX";});if(harmonyLoaded){ Debug.Log("HarmonyX detected. Blocking game from starting.");}}
Known Harmony types and patch registries present at runtime
Inside that assembly, Harmony exposes types in the HarmonyLib namespace. Useful signals include HarmonyLib.Harmony, HarmonyLib.PatchProcessor, and related patch metadata types. Once patches are applied, Harmony also keeps a runtime registry of patched methods. You can look for the known types first, then ask that registry if anything was patched.
Methods that suddenly have detours or wrappers they did not have at build time
This topic is a bit more complex, and detection is not as simple as with the other traces. HarmonyX does not change your DLL on disk, nor does it rewrite the managed IL sitting in memory. If you hash the loaded assembly and compare it with the file next to your game, both will look the same.What does change is the compiled method itself. After Unity has JIT compiled a method, Harmony can overwrite the entry point so every call jumps into a patched version. That jump is the signal you can check for.A simple approach is to force a method to compile, read the first bytes of its entry point, and keep that as a baseline early at startup. Later, read those bytes again. If they changed, something hooked the method.
usingSystem.Runtime.CompilerServices;voidAwake(){MethodInfo method =typeof(PlayerWallet).GetMethod(nameof(PlayerWallet.SpendCoins)); RuntimeHelpers.PrepareMethod(method.MethodHandle);// force JIT compileIntPtr entry = method.MethodHandle.GetFunctionPointer();// Read the first bytes at 'entry' and compare them// with a clean baseline taken at startup.}
One thing to keep in mind: this works well on Mono desktop builds, and a changed entry point proves a hook, not HarmonyX by name. For cheat detection that is usually fine, because any detour library that rewrites your methods leaves the same kind of fingerprint.You do not want to create all those checks by yourself? There are tools that can help you. Check out my Anti-Cheat solution that can help you detect HarmonyX and other cheating or modding tools. Plus a tone of more features to help you with your anti-cheat needs.
There is still one problem
Do you remember the example from the beginning of this article?
[HarmonyPatch(typeof(PlayerWallet),nameof(PlayerWallet.SpendCoins))]classSpendCoinsPatch{// Runs before SpendCoinsstaticboolPrefix(int amount){// Skip the original method completelyreturnfalse;}}
Especially the nameof(PlayerWallet.SpendCoins) part?All those fancy checks you implemented to detect HarmonyX are useless if an attacker can simply bypass them. An attacker could look for something like My.Amazing.HarmonyX.Detector.Detect and patch the body of the Detect method.There are two main ways to address this:
Outsource critical code to an external source
You can move part of your important code to an external source, such as your server, and load it at runtime. This makes it much harder for attackers to analyze your code in advance. Your detection logic can reside in this external code and execute before attackers have a chance to patch it. As a result, they won't see exactly what happens or know what to patch.However, this approach can be quite complicated to implement and maintain.
Use an obfuscation solution
Obfuscation can make your source code very difficult to understand and analyze. This makes it much harder for attackers to find and patch your detection logic. For example, a name like My.Amazing.HarmonyX.Detector.Detect would become something like IUQWEWQ.XACBSCA, making it significantly more difficult to locate and modify. While not impossible, it greatly increases the level of effort required.You might consider using my Obfuscator to obfuscate your source code. It is a powerful build-time tool that can make your code much harder to understand and analyze.
Your takeaway
HarmonyX is a runtime patching library, not a loader. BepInEx and MelonLoader bring it in so mods can rewrite Unity methods. Once a patch is applied, your method no longer runs as compiled. That is fine in many single player games, but it becomes a real problem when cheats or hacks hurt your revenue or other players.The good news is that HarmonyX leaves traces: loader folders, assemblies, known types and method entry points that suddenly jump somewhere else. You can check for those signals yourself, or use existing tools to help you.