Legacy Lands Library: a modular framework for Minecraft server plugins
Enterprise-grade modular framework for Minecraft server development with multi-tier caching, Redis Streams, resilient data processing, and modern Java concurrency. Built on Fairy Framework for production-scale plugin development.
At a glance
- What is it?
- The Legacy Lands Library is a set of Java 21 modules for Minecraft server development, published to a Maven repository and built on the Fairy Framework. It covers caching across Caffeine and Redis, MongoDB persistence through Morphia, annotation processing, AOP with classloader isolation, a script engine wrapper and a distributed data layer for player entities, with Spigot, Paper and Folia all supported.
- Who is it for?
- Adopt the Legacy Lands Library when you are building a Minecraft plugin that needs more than the platform provides, particularly caching across Caffeine and Redis, MongoDB persistence or distributed player data, and you are willing to depend on a Fairy Framework plugin at runtime. Do not adopt it for a small plugin, since the module count and the runtime requirement are not worth it.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the framework is and what Fairy brings
The Legacy Lands Library is described as an enterprise-grade modular framework for Minecraft server development, with multi-tier caching, Redis Streams, resilient data processing and modern Java concurrency, built on the Fairy Framework for production-scale plugin development.
The README's own summary is more concrete. It is a Modular Plugin Toolkit built on Fairy Framework, featuring modular design and leveraging modern Java 21 features, providing essential tools and utilities for modern Minecraft plugin development with cross-platform support for Spigot, Paper and Folia.
Fairy is the load-bearing dependency. The Quick Start makes it explicit that installing on the server means putting the fairy-lib-plugin and the jars of the modules you use, including the modules they depend on, into the plugins folder. That is a runtime dependency on another plugin rather than a library you shade into your own jar, and it changes how you deploy and how you debug: if the library plugin is missing or the wrong version, your plugin fails to load rather than throwing at runtime.
The cross-platform support is worth understanding because Folia is not just another API surface. Folia regions the world and runs them on separate threads, which breaks a great deal of plugin code that assumes a single main thread. A framework that supports Spigot, Paper and Folia across the same module set has already dealt with that split.
The repository is a Gradle build with build.gradle.kts, settings.gradle.kts, gradle.properties and the wrapper scripts, and each module has its own directory with its own README, which is where the detailed documentation lives.
The licence is MIT and the project site is legacylands.cn.
The module catalogue, and what each one is for
The Core Modules section lists nine modules, and the descriptions are more specific than the marketing language at the top.
The foundation module is the core foundation module, providing essential testing infrastructure, utilities and base abstractions for all library modules. Everything else depends on it, which makes it the piece you cannot skip.
The annotation module is an annotation processing framework with flexible scanning options and lifecycle management. The aop module is an enterprise-grade Aspect-Oriented Programming framework with ClassLoader isolation, providing performance monitoring, thread safety, logging and exception handling aspects. The ClassLoader isolation is the notable part, because on a Minecraft server the plugin classloader boundary is where aspect weaving usually breaks.
The commons module covers essential utilities including VarHandle injection, task scheduling, virtual thread scheduling, JSON operations and random object generation. The configuration module is a flexible configuration framework built on SimplixStorage with serialization support.
The mongodb module is streamlined MongoDB integration with Morphia for efficient data persistence, and the cache module is a multi-tier caching system integrating Caffeine and Redis, providing comprehensive lock management and a generic framework for thread-safe resource access.
The player module is the most ambitious: an enterprise-grade distributed data management framework building high-performance entity-relationship data layers, described as capable of seamlessly handling thousands of inter-entity relationship networks and state synchronization.
The script module is a script execution engine wrapper supporting Rhino, Nashorn and V8 JavaScript engines, described as powerful, flexible, extensible and high-performance.
And the experimental module holds modules that can significantly improve performance but may be too complex to use or temporarily unstable. Inside it, third-party-schedulers achieves distributed task processing via gRPC external task schedulers, currently implemented in Rust, enabling large plugin decoupling and performance improvements for backends that cannot directly access the Bukkit API. The stated use cases are machine learning, anti-cheat large data computation and mathematics.
A security module is listed as coming soon, which is worth noticing in a framework that otherwise leans heavily on caching, streams and distributed state.
Adding the library: Gradle, Maven and the runtime plugin
The Quick Start has three steps, and the first is dependency resolution.
Add the repository and the modules you need, with no authentication required:
repositories {
maven("https://repo.qwqdev.top/releases")
}
dependencies {
compileOnly("net.legacy.library:annotation:<version>")
}The latest version is shown in the Maven badge at the top of the README. The scope is compileOnly, which is the correct choice for a library you expect to be present at runtime through the fairy-lib-plugin rather than bundled into your own jar.
Then install on the server by putting fairy-lib-plugin and the jars of the modules you use, including the modules they depend on, into the plugins folder.
The third step declares the dependency in your plugin so it loads after the library:
fairy {
bukkitProperties().depends.add("annotation")
}That ordering matters on a Bukkit-style server, where plugin load order determines which classes exist when your plugin's static initialisers run.
The same dependency coordinates work for Maven, with the module name and version substituted:
<repositories>
<repository>
<id>legacy-lands</id>
<url>https://repo.qwqdev.top/releases</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>net.legacy.library</groupId>
<artifactId>module-name</artifactId>
<version>version</version>
<scope>provided</scope>
</dependency>
</dependencies>Artifacts are also published to GitHub Packages, which requires GitHub authentication, with credentials taken from the gpr.user and gpr.key properties or from the USERNAME and TOKEN environment variables. The primary repository needs no authentication, which is the simpler path unless your organisation requires artifacts to live in its own GitHub organisation.
For those who would rather not wire up a repository at all, the README documents downloading from the GitHub Actions workflow, with three distribution packages: -javadoc for generated API documentation, -plugin for the compiled plugin for direct server use, and -sources for source code with compiled classes, which is the recommended one for development.
Versioning and what the SNAPSHOT label actually means
The versioning section is short and unusual enough to quote in substance, because it does not say what you might expect.
Although the version number is currently still a SNAPSHOT, the README says, this does not mean it is unsuitable for production use. In fact, the project plans to extensively utilise this version in a large-scale plugin development project, and will release the first official version once it has thoroughly validated its stability and functionality.
So the current version is a moving snapshot that the maintainers intend to use in production themselves, with a non-snapshot release deferred until they have validated it. That is an honest statement about where the project is, and it carries a specific risk for anyone adopting it: the version you depend on today may change underneath you, because a SNAPSHOT in a Maven repository can be overwritten.
The repository has no GitHub releases at all, so there is no release page to pin against. The last push was on 2026-10-09, and the Maven badge at the top of the README is the version reference in practice.
For a library consumed through a Maven repository with a SNAPSHOT version, the practical advice is to record the exact artifact you deployed, including any timestamped snapshot identifier, so that a rebuild is reproducible. The alternative is to wait for the first official release, which the README says will come after validation.
The other repository is GitHub Packages, which does have versioned artifacts and requires authentication, and that is where a consumer who wants immutability should look.
Limits: a runtime plugin dependency, a fast-moving snapshot and an unfinished module
The limits are visible in what the README does not claim.
The first is the runtime dependency. The library is not a jar you shade into your plugin; the modules must be installed on the server as plugins, and your plugin must declare that it depends on them so the loader orders things correctly. That is a genuine operational cost. Every server running your plugin needs the same library versions, a version mismatch produces a load failure rather than a warning, and the module dependency graph means pulling in one module can pull in several others.
The second is the SNAPSHOT versioning. The README is candid that the current version is a snapshot and that it is intended for production use, but a moving version is a moving target. If your build resolves net.legacy.library:cache:the-snapshot at build time and the same coordinate at deploy time, you can get different bytes.
The third is the security module, listed as coming soon. For a framework whose cache module provides lock management and whose player module distributes state across a network, the absence of a security module is a notable gap in the catalogue rather than an oversight.
The fourth is the experimental module, which the README itself qualifies: modules that can significantly improve performance but may be too complex to use or temporarily unstable. The third-party-schedulers module is the most interesting of them, and the most demanding, since it moves work out of the server process to external gRPC schedulers written in Rust, which is a significant architectural step for a plugin and one that has to be operated by you.
The fifth is the platform ceiling implied by the module list. This is a framework built on modern Java 21 features and on the Fairy Framework, with the classloader isolation and the virtual thread scheduling in the commons module implying a specific runtime shape. A plugin that has to support older Java or a different server implementation is outside what this provides.
This framework against plain plugin development and against a smaller utility library
Two comparisons make the choice clearer.
The first is against writing the plugin yourself with nothing but the platform API. The difference in approach is that the framework supplies the parts every serious Minecraft plugin ends up writing: a cache across two tiers, a persistence layer, a configuration system, distributed player state, an aspect framework for cross-cutting behaviour and a script host. None of those is hard to write badly and expensive to write well, and the ones this framework offers are the ones where getting it wrong has consequences, like a Redis cache without proper lock management on a server with multiple threads touching the same key.
What you give up is control and the small footprint. Your plugin now depends on a runtime plugin being present, on a version of it, and on the modules it transitively pulls in. A plugin that displays a scoreboard does not need any of that.
The second comparison is against a single-purpose library. There are focused libraries for caching in a Minecraft plugin, and for MongoDB access, and using one of those gives you a smaller dependency with documentation for exactly the thing you need. The difference in approach is that the framework's modules are designed to work together, with the foundation abstractions, the AOP aspects and the lock management in the cache module assuming the rest of the stack is present. Choosing the framework means accepting that design coherence; choosing the focused library means accepting that you will assemble the pieces yourself and that they will not share the same abstractions.
The practical decision usually comes down to scale. If you are running a small server with a plugin that needs a database connection, a focused library is the better answer. If you are running the kind of large-scale deployment the maintainers describe planning to use it in, with distributed schedulers, entity-relationship player data and multi-tier caching, the coherence is the point.
Editorial conclusion
Adopt the Legacy Lands Library when you are building a Minecraft plugin that needs more than the platform provides, particularly caching across Caffeine and Redis, MongoDB persistence or distributed player data, and you are willing to depend on a Fairy Framework plugin at runtime. Do not adopt it for a small plugin, since the module count and the runtime requirement are not worth it. Verify first which modules you actually need, since each is a separate artifact with its own dependencies, that the Fairy library plugin is loaded first, and that the version you pin has the documentation for your specific module.
Frequently asked questions
Which modules does the Legacy Lands Library provide?
The core modules are foundation, which provides base abstractions and testing infrastructure, annotation for annotation processing, aop for aspect-oriented programming with classloader isolation, commons for utilities including virtual thread scheduling and VarHandle injection, configuration built on SimplixStorage, mongodb using Morphia, cache combining Caffeine and Redis, player for distributed entity-relationship player data, and script for a wrapper over the Rhino, Nashorn and V8 JavaScript engines. There is also an experimental module and a security module listed as coming soon.
How do I add the Legacy Lands Library to a Maven or Gradle build?
Add the repository at https://repo.qwqdev.top/releases, which needs no authentication, and declare the modules you need as compileOnly dependencies under the groupId net.legacy.library, for example net.legacy.library:annotation:<version>. On the server you also install the fairy-lib-plugin and the module jars, and declare the dependency in your plugin with fairy { bukkitProperties().depends.add("annotation") } so it loads afterwards.
Is it safe to use the Legacy Lands Library in production?
The README says so explicitly: although the version number is currently still a SNAPSHOT, this does not mean it is unsuitable for production use, and the maintainers plan to use this version in a large-scale plugin development project, releasing the first official version once stability and functionality have been thoroughly validated. Since a snapshot can be overwritten, record the exact artifact you deployed.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/legacylands-legacy-lands-library)Was this useful?