
FoliaLib: Managing Schedulers for Modern Minecraft Servers
FoliaLib (TechnicallyCoded/FoliaLib)
This is a wrapper library for aiding in supporting the Folia Paper Fork. This library adds multiple scheduler options to use instead of the Bukkit or Folia native schedulers.
If you're running a custom Minecraft server with plugins, you've probably noticed that Paper and Spigot schedulers work fine until they don't. Switch to Folia - Paper's new multithreaded fork - and suddenly half your plugins break because their task scheduling assumes a single thread. That's the problem FoliaLib solves.
What Folia Is (And Why It Matters)
Folia is Paper's experimental fork that distributes server load across multiple CPU cores instead of running everything on one thread. It's faster and more stable on high-player servers, which sounds great. The catch? It breaks a decade of plugin assumptions. Code that worked fine on single-threaded servers can crash, cause race conditions, or deadlock entirely when Folia runs it.
Most servers still run Paper. But Folia adoption is growing, and if you're a plugin developer, you can't just ignore it. FoliaLib is the bridge that lets you support both worlds at once.
The Scheduling Problem FoliaLib Solves
Task scheduling is where most Folia compatibility issues hide. You've probably written code like this at some point:
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> {
// Do something
}, 20L);On Paper, this runs on the main thread. On Folia? It still runs on a thread, but not necessarily *the* thread your world data lives on. So that mismatch causes crashes when you try to access blocks, entities, or players without proper synchronization.
FoliaLib replaces the native scheduler with smart wrappers that know which thread they're running on. It detects whether you're on Folia or Paper, then picks the right scheduler automatically. You write once, it works everywhere.
How FoliaLib Works
FoliaLib is a wrapper library that sits between your plugin and the Bukkit scheduler. Instead of calling Bukkit directly, you use FoliaLib's scheduler class, which internally picks the best scheduler for your server:
- On Folia: Uses Folia's region-aware scheduler to keep tasks tied to the right thread
- On Paper or Spigot: Falls back to the standard Bukkit scheduler
- On older servers: Uses compatibility workarounds for versions as far back as 1.8.8
You don't write conditional code for each server type. FoliaLib handles the detection and routing behind the scenes. Deploy the same plugin JAR to Folia, Paper, and Spigot - it just works.
Installing and Setting Up FoliaLib
FoliaLib is distributed via a Maven repository and added as a compile-time dependency. You'll shade it into your plugin JAR (a standard practice to avoid conflicts).
If you're using Maven, add the repository and dependency:
<repositories>
<repository>
<id>tcoded-releases</id>
<url>https://repo.tcoded.com/releases</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.tcoded</groupId>
<artifactId>FoliaLib</artifactId>
<version>SET_VERSION_HERE</version>
<scope>compile</scope>
</dependency>
</dependencies>Then configure Maven Shade to relocate the package (critical step) so it doesn't conflict with other plugins that also use FoliaLib:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>com.tcoded.folialib</pattern>
<shadedPattern>your.package.name.lib.folialib</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>If you use Gradle, the setup is similar - add the repository, declare the dependency, and configure the Shadow plugin to relocate the package. (The README has examples if you need them.)
Key Features and Practical Examples
FoliaLib abstracts away the scheduler differences, but it also adds features that make writing safe, concurrent code easier.
The main feature is multiple scheduler options. Instead of one global scheduler, FoliaLib gives you context-aware scheduling: entity schedulers (tasks tied to a specific entity), region schedulers (tasks tied to a world region), and async schedulers. You pick the one that matches what your task is actually doing. If you're modifying an entity, use the entity scheduler and FoliaLib guarantees that task runs on the thread responsible for that entity.
Another useful feature is that FoliaLib handles the version compatibility mess. You can target servers from 1.8.8 all the way to 1.21+ without writing workarounds. That's helpful if you're maintaining a plugin that's been around for years and you want to support both ancient and modern servers.
There's also better error handling for edge cases. The native Folia scheduler is still new and occasionally has surprises. FoliaLib smooths over some of those rough edges with internal fixes.
Common Pitfalls and How to Avoid Them
The biggest mistake new users make is forgetting to relocate the package. If two plugins both include FoliaLib without relocation, they'll conflict and one will shadow the other. Your plugin might work fine in testing and break mysteriously on a server with other Folia-compatible plugins. Always relocate.
Another gotcha: FoliaLib is still in active development (version 0.5.1 as of this writing). The API may change between releases. Check the GitHub issues page before upgrading, especially if your plugin is heavily integrated with FoliaLib's scheduler.
And don't assume that using FoliaLib automatically makes your plugin thread-safe. FoliaLib handles scheduler routing, but if you're accessing shared state from multiple tasks without synchronization, you'll still have race conditions. It's a tool that helps you write safe code, not magic that makes unsafe code safe.
Actually, a practical tip: if you're porting an existing plugin to FoliaLib, start by leaving your scheduling code as-is and just running on Folia. Let it break in predictable ways, then incrementally switch tasks to FoliaLib's scheduler. Trying to refactor everything at once usually creates more bugs than it fixes.
Who Should Use FoliaLib
If you maintain a plugin, especially one with timers, entity tracking, or background tasks, FoliaLib is worth adopting. It's particularly valuable if your plugin is used on both Paper and Folia servers - instead of maintaining two codebases or littering your code with compatibility checks, you use FoliaLib and ship one JAR.
If you're building a server network and want to experiment with Folia's performance benefits without losing plugin compatibility, FoliaLib lets you do that. Plugin developers can add support gradually, and FoliaLib handles the fallback to Paper's scheduler in the meantime.
If you're starting a new plugin today and want it to be future-proof, building on FoliaLib is a smart move. Folia adoption will only increase as it matures.
On the flip side, if you're running a small Paper server with a handful of simple plugins, FoliaLib doesn't matter to you. And if you're developing a plugin that doesn't use any scheduler at all (pure commands, event listeners), you probably don't need it.
Context Within the Larger Folia Ecosystem
FoliaLib isn't the only way to handle Folia compatibility. Some plugins just check the server type and use conditional logic. Some developers write adapters specific to their plugin. But FoliaLib is the community standard because it centralizes the complexity and lets individual developers focus on their plugin logic instead of scheduler internals.
while you're working on plugin compatibility, you might also need tools for other aspects of server administration. Look, if you're documenting your server's capabilities or building client resources, the Minecraft Block Search tool is handy for looking up block properties, and the Minecraft Text Generator can help with server messages and documentation.
FoliaLib is actively maintained by the community. Recent updates (version 0.5.1) include refactors to improve reliability and better support for newer Minecraft versions. If you find bugs or have feature requests, the GitHub issues page is the place to report them.
TechnicallyCoded/FoliaLib - MIT, ★126