Generating Minecraft mods with Forge and Fabric
How Codexe scaffolds Forge/NeoForge and Fabric mod projects, what goes in mods.toml and fabric.mod.json, and how the two loaders differ.
Mods are not plugins
A Bukkit-family plugin runs on the server only, and vanilla clients can join without installing anything. A mod modifies the game itself, which means it can add real blocks, items, entities and rendering - and usually has to be installed on the client as well as the server.
If your idea needs new blocks or items that players see in their inventory, you need a mod. If it is about server behaviour, commands or rules, a plugin is simpler and reaches more players.
Forge and NeoForge
Codexe scaffolds a complete Gradle project for Forge and NeoForge: build script, mod descriptor, registry classes and the entry point with its event bus subscriptions.
src/main/
├── java/com/example/mymod/
│ ├── MyMod.java // @Mod entry point
│ ├── init/ModItems.java // DeferredRegister<Item>
│ └── init/ModBlocks.java
└── resources/
├── META-INF/mods.toml
└── assets/mymod/...mods.toml is Forge’s descriptor. It declares the mod id, the loader version range and dependency constraints:
modLoader="javafml"
loaderVersion="[47,)"
license="MIT"
[[mods]]
modId="mymod"
version="1.0.0"
displayName="My Mod"
[[dependencies.mymod]]
modId="minecraft"
mandatory=true
versionRange="[1.20.1,1.21)"
ordering="NONE"
side="BOTH"The modId must be lowercase and must match the id used in code and in the asset paths. Registration goes through DeferredRegister rather than direct registry writes, because Forge controls when registries are open.
Fabric
Fabric projects use the Loom Gradle plugin and a JSON descriptor. The loader is lighter than Forge and tends to update to new Minecraft versions sooner.
{
"schemaVersion": 1,
"id": "mymod",
"version": "1.0.0",
"name": "My Mod",
"environment": "*",
"entrypoints": {
"main": ["com.example.mymod.MyMod"]
},
"mixins": ["mymod.mixins.json"],
"depends": {
"fabricloader": ">=0.15.0",
"minecraft": "~1.20.1"
}
}The entrypoints block is what Fabric calls on load, and it is split by environment - main, client and server. Putting client-only rendering code in main is a common way to crash a dedicated server.
Mixins
Fabric has no large built-in event bus, so mods change vanilla behaviour by injecting into game classes with Mixin. Codexe generates the mixin JSON and the mixin classes alongside the mod when your request needs them.
Choosing a loader
| Forge / NeoForge | Fabric | |
|---|---|---|
| Descriptor | mods.toml | fabric.mod.json |
| Build | Gradle + ForgeGradle | Gradle + Loom |
| Hooks | Event bus | Mixins + events |
| Best for | Large content mods, existing ecosystems | Lightweight mods, fast version updates |
Start building
Use the Forge mod generator or the Fabric mod generator.