Guide

How to make a Folia plugin

Updated October 18, 2026

Folia is a fork of Paper that splits the world into regions and ticks them on different threads, so large servers can use many CPU cores. There is no single main thread anymore, and that breaks the usual Bukkit scheduler. A Folia plugin is a Paper plugin written for that model, and it must say so in its plugin.yml.

An example with the timing details Folia needs.

Generate this with Codexe

Step by step

  1. 1.Check that you need Folia

    Folia helps servers with many players spread out across the world. Most servers run Paper; many popular plugins do not support Folia, so check the ones you rely on first.

  2. 2.Build against the Folia API

    Use the folia-api dependency for your version from the PaperMC repository, with provided scope, in a Maven or Gradle project.

  3. 3.Replace the Bukkit scheduler

    Bukkit.getScheduler() does not work on Folia. Use the region scheduler for work at a location, the entity scheduler for work on a player or mob, the global region scheduler for world-wide tasks, and the async scheduler for I/O.

  4. 4.Touch things only from their own region

    Change a block or an entity only on the thread that owns it. Use teleportAsync instead of teleport, and schedule onto the target's region before changing it.

  5. 5.Declare Folia support

    Add folia-supported: true to plugin.yml. Without it Folia refuses to load the plugin.

  6. 6.Test on a Folia server

    Compiling proves the code builds against the Folia API, not that it is thread safe. Run it on a Folia test server with several players in different places.

The four schedulers

SchedulerGet it withUse it for
RegionBukkit.getRegionScheduler()Work at a world location: placing blocks, spawning
Entityentity.getScheduler()Work on one player or mob, it follows them across regions
Global regionBukkit.getGlobalRegionScheduler()World time, weather, things not tied to a location
AsyncBukkit.getAsyncScheduler()Database, files, web requests, never the world

What usually breaks

  • Repeating tasks for all players: a single loop over every online player no longer works; schedule a task on each player's entity scheduler instead.
  • Teleports and warmups: "teleport after 3 seconds" needs the entity scheduler and teleportAsync.
  • Shared data: maps and counters used from several regions must be thread safe, for example concurrent collections.
  • Dependencies: a library that calls the Bukkit scheduler throws UnsupportedOperationException on Folia.

One plugin for Paper and Folia

The region, entity, global and async schedulers are also part of the Paper API on current versions, so a plugin that uses only them and declares folia-supported: true can run on both Paper and Folia. That is often the best target: one .jar for every server.

With Codexe

Choose the Folia type. The generated plugin schedules work with the region, entity, global region and async schedulers, declares folia-supported: true and builds against the Folia API with Maven. It is compiled and checked before it is Ready.

Put timing details in the request ("every minute for each online player", "teleport after 3 seconds"): that is where Folia code differs most. Try it now does not run Folia servers yet, so test the .jar on your own Folia server.

Questions

Do Paper plugins run on Folia?

Only if they are written for it and declare folia-supported: true. A normal Paper plugin that uses the Bukkit scheduler is refused or fails.

Does a Folia plugin run on Paper?

Yes, when it uses only APIs that Paper also has, which includes the Folia schedulers on current Paper versions.

My Folia plugin throws an exception about the scheduler

Some code, often from a library, still uses the Bukkit scheduler. Ask the project chat to move it to the region or entity scheduler.

Make a Folia plugin

This prompt opens ready to send:

“A Folia 1.21.4 plugin called RTP: /rtp teleports the player to a random safe location within 5000 blocks after a 3-second warmup that cancels on movement, using the entity scheduler and teleportAsync, a 10-minute cooldown per player saved in SQLite, folia-supported: true, radius, cooldown and messages in config.yml.”

Generate this with Codexe
How to make a Folia plugin (region schedulers) | Codexe