So you've run a vanilla server, maybe added a few plugins, and now you want actual mods. New blocks, new mobs, machines, magic, the works. The thing is, modded servers work pretty differently from plugin servers, and that trips up a lot of people the first time. This guide walks you through the whole process, from picking a loader to reading the logs when something breaks.
Let's clear up one big thing first. Plugins and mods are not the same. Plugins (the kind you'd run on Paper or Spigot) live entirely on the server and players join with a normal unmodified client. Mods are different. They usually change the actual game, so the server and every player need the same mods installed. Keep that in your head, because it changes how you plan everything.
Fabric versus Forge, in plain terms
A mod loader is the layer that lets mods hook into Minecraft. You can't just drop a mod jar onto vanilla and expect it to run. You need a loader, and the two big ones are Fabric and Forge. (There's also NeoForge now, which is a fork of Forge that a lot of mods have moved to, but the ideas are the same.)
Here's the short version. Forge has been around forever. It's heavier, it's been the home for the big kitchen sink modpacks, and a lot of long running tech and magic mods live there. Fabric is lighter and updates to new Minecraft versions faster. The performance mods most people want, like Lithium and Starlight, are Fabric mods.
You don't pick based on which is "better." You pick based on the mods you want to run. Go find the mods first. If they're Forge mods, you run Forge. If they're Fabric mods, you run Fabric. A Forge mod will not load on a Fabric server, and vice versa. There's no mixing them. Honestly, the most common beginner mistake is downloading a Forge version of a mod and trying to run it on Fabric, then wondering why nothing shows up.
What about a modpack?
If you're following a modpack from CurseForge or Modrinth, the loader is already decided for you. The pack page tells you it's Forge 1.20.1 or Fabric 1.21, or whatever. Match that exactly and your life gets a lot easier. Most pack platforms also give you a server pack download that bundles the loader and all the mods together, which saves you a ton of manual work.
Installing the loader on the server
This is the part that's genuinely different from vanilla. A vanilla server is one jar. A modded server runs the loader instead, and the loader pulls in Minecraft and your mods.
For Fabric, you grab the Fabric server launcher jar from the official Fabric site. It's a small file. You drop it in your server folder, then run it once and it downloads the matching Minecraft server and the libraries it needs. The startup command looks roughly like this:
java -Xms2G -Xmx4G -jar fabric-server-launch.jar nogui
For Forge, you download the Forge installer for your exact Minecraft version, run it in "install server" mode, and it spits out the server files plus a run script. Newer Forge versions give you a run.sh or run.bat instead of a single jar, and you're meant to launch through that. The JVM arguments live in a file called user_jvm_args.txt, which is where you set your RAM.
Either way, the first launch will probably stop and make you accept the EULA. Open eula.txt, change eula=false to eula=true, save, and start it again. Same as vanilla.
If you're on a control panel, this gets easier. On our panel at panel.bytte.cloud you can pick a Fabric or Forge egg, choose the version, and it sets the loader up for you so you're not hand running installers over SSH. Plenty of other Pterodactyl style panels do the same. Either way, the concepts below still apply.
Matching versions, the part people get wrong
This is where most modded servers die before they even start. Three things have to line up:
- The Minecraft version (like 1.20.1 or 1.21.1)
- The loader (Fabric or Forge) and its version
- Every mod you install
A mod built for 1.20.1 Fabric will not load on 1.21 Fabric. It usually won't even load on 1.20.4. Minor version bumps break mods all the time. So when you download a mod, check the file you're grabbing. On Modrinth and CurseForge, every mod file is tagged with the Minecraft versions and loaders it supports. Read that tag before you click download.
A quick warning: do not just grab the newest file. The newest file is often for the newest Minecraft version, which may not be the one your server runs. Filter the download page to your exact version first. I've lost more time than I'd like to admit to downloading a 1.21 jar for a 1.20.1 server.
My advice for a first modded server is to pick a slightly older, well supported version like 1.20.1. The newest Minecraft release usually has the fewest mods ported to it, and you'll spend your evening hunting for things that don't exist yet.
The mods folder and dependencies
Once the loader is installed and started once, you'll see a mods folder appear in your server directory. That's where mod jars go. One jar per mod, dropped straight in, no subfolders. Restart the server and it loads them.
Now the dependency part. Many Fabric mods need Fabric API to run. It's a shared library that a huge number of mods build on top of. If a mod needs it and it's missing, the mod just won't load, and sometimes the server won't start at all. So if you run Fabric, grab Fabric API (the right version for your Minecraft version, of course) and put it in the mods folder along with everything else.
Forge has its own version of this. Some Forge mods depend on libraries like Kotlin for Forge or other shared mods. The mod's download page will almost always list "required dependencies." Read that section. If a mod says it needs another mod, you need both, and both need to match your version and loader.
Here's the rule I'd burn into your memory: a mod's dependencies are not optional. They're not extras. If the page lists a required library, the mod will not work without it. Half the "my server won't start" messages we see come down to a missing dependency.
Clients have to match the server
This is the big mental shift from plugins. With most mods, players cannot join with a vanilla client. Every player needs the loader and the same mods installed on their own machine, matched to the same versions.
So if your server runs Fabric 1.20.1 with twenty mods, each player installs Fabric for 1.20.1 and the same twenty mods. The easiest way to hand this out is a modpack on Modrinth or CurseForge that people install through a launcher like the Modrinth App, the CurseForge app, or Prism Launcher. They click install, it pulls every mod at the right version, and they're done.
There are exceptions worth knowing. Some mods are server side only, and some are client side only. A performance mod a player installs just for their own framerate doesn't need to be on the server. And a few server side mods don't require anything from the client at all. But the general case is simple: mismatched mod lists mean the player gets kicked at login, usually with a message about a mod being missing or a different version. If players are getting booted the moment they connect, this is almost always why.
Reading the logs when it breaks
It will break. That's normal. The good news is modded Minecraft is pretty loud about why, if you actually read the console.
When the server fails to start, look at the latest log. On most setups that's the live console, or logs/latest.log in your server folder. Scroll to where it crashed and look for words like Missing, requires, incompatible, or dependency. Fabric in particular prints a clean list when something is wrong. You'll see something like this:
Incompatible mods found!
net.fabricmc.loader.impl.FormattedException:
Mod 'Some Mod' (somemod) 1.2.0 requires version 0.91.0 or
later of fabric, which is missing!
That message is telling you exactly what to do. It wants Fabric API 0.91.0 or newer, and it can't find it. Go download that version, drop it in, restart. Forge gives you similar messages, sometimes pointing at a missing library or a version conflict between two mods.
A few patterns to recognize:
- "requires version X which is missing" means a dependency isn't there. Add it.
- "requires version X but found Y" means you have the dependency, but the wrong version. Fix the version.
- Two mods named in one error usually means they conflict. Remove one and test.
- A crash mentioning a specific class right at startup often means a mod built for a different Minecraft version. Recheck that jar's tag.
When you're not sure which mod broke things, pull half the mods out, start the server, and add them back in batches until it breaks again. It's tedious but it works, and it beats guessing.
Performance mods are worth it
Modded servers are heavier than vanilla, so it's smart to add performance mods early. On Fabric, the standout server side ones are Lithium and Starlight.
Lithium rewrites a lot of the game's internal logic (mob AI, physics, redstone, hopper ticks) to be faster without changing how anything behaves. Starlight replaces the lighting engine, which is one of the worst lag sources during world generation and chunk loading. Both are server safe, both are basically free performance, and neither changes gameplay. I'd put them on almost any Fabric server.
One nice thing: Lithium and Starlight are server side improvements, so they help the whole server even though players don't strictly need them on the client. Forge has its own performance options too, though the popular performance mod scene leans heavily Fabric these days.
If you want to actually see where your server is spending time, install spark. It's a profiler mod that works on Fabric and Forge, and it'll show you which mod or which chunk is eating your tick time. When someone says "the server is lagging," spark turns that into a real answer instead of a guess.
A sensible first build
If this is your first time, keep it small. Pick 1.20.1, pick Fabric, install Fabric API, add Lithium and Starlight, and add maybe five mods you actually care about. Get that running clean. Then add more in small batches, restarting and checking the log each time, so when something breaks you know exactly which jar did it.
Modded servers feel fiddly at first, but the loop is always the same: match the version, match the loader, feed the dependencies, keep the clients in sync, and read the log when it complains. Do that a few times and it stops being scary. Then you can spend your time actually playing instead of staring at a crash report.



