{"id":48446116,"url":"https://github.com/florianreuth/asmfabricloader","last_synced_at":"2026-04-06T18:00:45.269Z","repository":{"id":220871740,"uuid":"752797788","full_name":"florianreuth/AsmFabricLoader","owner":"florianreuth","description":"A series of cursed Fabric hacks and utilities which break everything.","archived":false,"fork":false,"pushed_at":"2026-03-12T15:40:00.000Z","size":573,"stargazers_count":21,"open_issues_count":0,"forks_count":5,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-26T14:33:34.316Z","etag":null,"topics":["asm","cursed","fabric","grossfabrichacks","injection","mixin"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/florianreuth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"FlorianMichael","custom":["https://florianmichael.de/donate"]}},"created_at":"2024-02-04T20:33:09.000Z","updated_at":"2026-03-12T15:40:07.000Z","dependencies_parsed_at":"2024-02-19T18:44:51.462Z","dependency_job_id":"0fb41905-c180-4958-a67d-876909729d5a","html_url":"https://github.com/florianreuth/AsmFabricLoader","commit_stats":null,"previous_names":["florianmichael/asmfabricloader","florianreuth/asmfabricloader"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/florianreuth/AsmFabricLoader","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/florianreuth%2FAsmFabricLoader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/florianreuth%2FAsmFabricLoader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/florianreuth%2FAsmFabricLoader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/florianreuth%2FAsmFabricLoader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/florianreuth","download_url":"https://codeload.github.com/florianreuth/AsmFabricLoader/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/florianreuth%2FAsmFabricLoader/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31483380,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T17:22:55.647Z","status":"ssl_error","status_checked_at":"2026-04-06T17:22:54.741Z","response_time":112,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asm","cursed","fabric","grossfabrichacks","injection","mixin"],"created_at":"2026-04-06T18:00:44.356Z","updated_at":"2026-04-06T18:00:45.259Z","avatar_url":"https://github.com/florianreuth.png","language":"Java","funding_links":["https://github.com/sponsors/FlorianMichael","https://florianmichael.de/donate"],"categories":[],"sub_categories":[],"readme":"# AsmFabricLoader\n\nA series of cursed Fabric hacks and utilities which break everything.\n\n\u003c!-- TOC --\u003e\n* [AsmFabricLoader](#asmfabricloader)\n  * [Why?](#why)\n  * [Contact](#contact)\n  * [How to add this to your project](#how-to-add-this-to-your-project)\n    * [Gradle/Maven](#gradlemaven)\n    * [Jar File](#jar-file)\n  * [How to use](#how-to-use)\n    * [PreLaunch Entry Points](#prelaunch-entry-points)\n    * [Get a Java instrumentation (Requires Java 9+)](#get-a-java-instrumentation-requires-java-9)\n    * [Unmixer](#unmixer)\n    * [Jar Booter](#jar-booter)\n    * [Early riser](#early-riser)\n    * [Class Transform (Requires Java 9+)](#class-transform-requires-java-9)\n      * [Setting up mappings](#setting-up-mappings)\n      * [Transformer config](#transformer-config)\n      * [Example transformer](#example-transformer)\n      * [Registering transformers](#registering-transformers)\n    * [Environments](#environments)\n    * [Debug options](#debug-options)\n    * [Testing](#testing)\n\u003c!-- TOC --\u003e\n\n## Why?\n\nThere are many use cases for direct ASM injections and the power to re-transform every loaded class.\n\nThis is basically a cleanup rewrite of [GrossFabricHacks](https://github.com/Devan-Kerman/GrossFabricHacks/tree/master)\nusing the [ClassTransform](https://www.github.com/Lenni0451/ClassTransform)\nand [Reflect](https://www.github.com/Lenni0451/Reflect) libraries.\n\nIt also provides the same functionality as [MixinSquared](https://github.com/Bawnorton/MixinSquared).\n\n## Contact\n\nIf you encounter any issues, please report them on\nthe [issue tracker](https://github.com/florianreuth/AsmFabricLoader/issues).  \nIf you just want to talk or need help with AsmFabricLoader feel free to join\nmy [Discord](https://florianreuth.de/discord).\n\n## How to add this to your project\n\n### Gradle/Maven\n\nTo use AsmFabricLoader with Gradle/Maven you can\nuse [the Maven Central repository](https://mvnrepository.com/artifact/de.florianreuth/asmfabricloader)\nor [my own repository](https://maven.florianreuth.de/#/releases/de/florianreuth/asmfabricloader).  \nYou can also find instructions how to implement it into your build script there.\n\n### Jar File\n\nIf you just want the latest jar file you can download it\nfrom [my build server](https://build.florianreuth.de/job/AsmFabricLoader), [GitHub Actions](https://github.com/florianreuth/AsmFabricLoader/actions)\nor use the [releases tab](https://github.com/florianreuth/AsmFabricLoader/releases).\n\n## How to use\n\nAsmFabricLoader allows you to access a series of utilities and hacks to make your life easier.\n\n### PreLaunch Entry Points\n\nAsmFabricLoader adds an even more early entry point than FabricMC's `PreLaunchEntrypoint`.\n\nYou can use the `PrePreLaunchEntrypoint`, which will be called when Fabric bootstraps the mixin service. The name\nof the entry point is `afl:prePreLaunch`.\n\nThe `PrePrePreLaunchEntrypoint` is the earliest entry point possible. It is getting bootstrapped before the loader\neven starts. The name of the entry point is `afl:prePrePreLaunch`.\n\nYou can use both just like the `PreLaunchEntrypoint` from FabricMC.\n\n### Get a Java instrumentation (Requires Java 9+)\n\nAsmFabricLoader allows you to get a Java instrumentation instance which you can use to transform classes directly.\n\nYou can use the `InstrumentationEntrypoint` to get the instrumentation instance. The name of the entry point is\n`afl:instrumentation`.\n\n### Unmixer\n\nAsmFabricLoader adds a new API which allows you to unload Mixin classes meaning they aren't injected anymore. This is\nuseful if another mod is breaking your Mixins or if you want to unload Mixins after they have been applied.\n\n```java\nfinal Unmixer unmixer = AsmFabricLoader.getLoader().getUnmixer();\n\n// This method accepts the mixin classes of all loaded mods including the Fabric internals\nunmixer.unloadMixinClass(\"net/fabricmc/api/mixin/v1/MixinEnvironment\");\n```\n\nYou can also use the Unmixer via the `fabric.mod.json` file:\n\n```json\n{\n  \"custom\": {\n    \"afl:unmixer\": [\n      \"net.fabricmc.api.mixin.v1.MixinEnvironment\"\n    ]\n  }\n}\n```\n\nYou can also group the packages together:\n\n```json\n{\n  \"custom\": {\n    \"afl:unmixer\": {\n      \"net.fabricmc.api.mixin.v1\": [\n        \"MixinEnvironment\"\n      ]\n    }\n  }\n}\n```\n\n### Jar Booter\n\nAsmFabricLoader allows you to define a list of folders where it will load all jar files from to the front of the\nclasspath.\nThis can be useful if you want to allow the user to replace a library jar file you are using with a different version.\n\n```json\n{\n  \"custom\": {\n    \"afl:jarbooter\": [\n      \"libs\"\n    ]\n  }\n}\n```\n\nThis will load all jar files from the run directory/libs folder to the front of the classpath.\n\n### Early riser\n\nUtility to create and invoke mod entrypoints before Fabric has finished loading entrypoints. See the `EarlyRiser` class\n\n### Class Transform (Requires Java 9+)\n\nAsmFabricLoader bootstraps the [ClassTransform](https://www.github.com/Lenni0451/ClassTransform) library which allows\nyou to transform classes directly without using Mixins.\n\n#### Setting up mappings\n\nAsmFabricLoader uses tiny mappings internally to remap Minecraft classes for transformers.\n\nAsmFabricLoader itself **does not** ship these mappings. Your mod has to provide the Tiny mappings file so that AFL can\nload it at runtime.\n\nAsmFabricLoader looks for a resource named:\n\n- `/afl_mappings.tiny`\n\nYou can override this path per mod via `fabric.mod.json` using `afl:mappings_path`. The value must be a string\nand is resolved as a resource path inside the mod jar (a leading / is added automatically if missing), for example:\n\n```json\n{\n  \"custom\": {\n    \"afl:mappings_path\": \"custom/afl_mappings.tiny\"\n  }\n}\n```\n\nExample for **Gradle Kotlin DSL** (`build.gradle.kts`) in your mod project:\n\n```kotlin\ntasks {\n    jar {\n        dependsOn(configurations[\"mappings\"])\n        val mappingsJar = configurations[\"mappings\"].resolvedConfiguration.resolvedArtifacts.firstOrNull {\n            it.name.contains(\"mappings\") || it.name.contains(\"yarn\")\n        }?.file\n\n        if (mappingsJar != null \u0026\u0026 mappingsJar.exists()) {\n            val mappingsFile = zipTree(mappingsJar).matching {\n                include(\"mappings/mappings.tiny\")\n            }.singleFile\n\n            from(mappingsFile) {\n                rename { \"afl_mappings.tiny\" }\n            }\n        }\n    }\n}\n```\n\nExample for **Gradle Groovy DSL** (`build.gradle`) in your mod project:\n\n```groovy\ntasks {\n    jar {\n        dependsOn(configurations.mappings)\n        def mappingsJar = configurations.mappings\n            .resolvedConfiguration\n            .resolvedArtifacts\n            .find { it.name.contains(\"mappings\") || it.name.contains(\"yarn\") }\n            ?.file\n\n        if (mappingsJar != null \u0026\u0026 mappingsJar.exists()) {\n            def mappingsFile = zipTree(mappingsJar).matching {\n                include \"mappings/mappings.tiny\"\n            }.singleFile\n\n            from(mappingsFile) {\n                rename { \"afl_mappings.tiny\" }\n            }\n        }\n    }\n}\n```\n\n#### Transformer config\n\nYou just have to create a json file called `\u003cmodid\u003e.classtransform.json` in your resources folder and add the following\n\n```json\n{\n  \"package\": \"net.example.injection.transformer\",\n  \"java\": [\n  ],\n  \"mixins\": [\n  ]\n}\n```\n\nThe `package` field is the package where your transformers are located.\n\nNow AsmFabricLoader provides two ways to add transformers to the ClassTransform library:\n\nThe `java` field will apply all the transformers using a runtime injected java agent after Mixins and the loader\nhas been initialized. Meaning you can transform all classes in your runtime, even Java standard library classes.\n\nThe `mixins` field will apply all the transformers before Mixins are getting applied, therefore you can only add\ntransformers targeting other mods mixin classes. These transformers will be applied before those Mixins are getting\napplied to the game code, this is basically a replacement for [MixinSquared](https://github.com/Bawnorton/MixinSquared).\n\n#### Example transformer\n\n```java\n@CTransformer(String.class)\npublic class Test {\n\n    @CInline\n    @CInject(method = \"equals\", target = @CTarget(\"HEAD\"))\n    public void printInput(Object anObject, InjectionCallback callback) {\n        System.out.println(\"Input: \" + anObject);\n    }\n\n}\n```\n\n#### Registering transformers\n\nTo register your json file, you have to add the following to your `fabric.mod.json` file:\n\n```json\n{\n  \"custom\": {\n    \"afl:classtransform\": \"\u003cmodid\u003e.classtransform.json\"\n  }\n}\n```\n\n### Environments\n\nAsmFabricLoader allows you to limit the execution of all the features to specific environments. This can be useful if\nyou want to use the same mod jar file for multiple environments.\n\nThis snippet will only apply the unmixer if the mod is loaded on the client:\n\n```json\n{\n  \"custom\": {\n    \"afl:client:unmixer\": [\n    ]\n  }\n}\n```\n\n### Debug options\n\nThere are a few system properties you can enable to debug AsmFabricLoader:\n\n```-DAsmFabricLoader.debug=true``` will print a lot of useful debug information including loading states\n\n```-Dclasstransform.dumpClasses=``` will dump all classes transformed by ClassTransform\nto `run directory` / `classtransform`\n\n### Testing\n\nThe `TestMod` submodule contains a Fabric mod to test various features of AsmFabricLoader. You can run the tests by\nbuilding both root project and the test mod project and then running them in a production environment.\n\nA test running successfully will be indicated by the following message in the console:\n\n```\n[TestMod] \u003cNameOfTheTest\u003e passed!\n```\n\nAll tests have been passed if you see the following message in the console:\n\n```\n[TestMod] All tests passed!\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflorianreuth%2Fasmfabricloader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflorianreuth%2Fasmfabricloader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflorianreuth%2Fasmfabricloader/lists"}