KotlinFramework is a lightweight framework for writing Paper plugins in Kotlin without the usual boilerplate.
I built this because I kept copy-pasting the same companion object, instance setup, and registerEvents into every single plugin. It's not trying to replace anything big, it just removes the repetitive parts so you can focus on actual plugin logic.
Works with Paper 1.21+ and Java 21+.
What it does
- Base class (KotlinFramework) that handles instance, startup logging, and safe error handling on enable/disable
- Inline command registration: no separate class needed for simple commands
- Inline event listening: no @EventHandler, no separate Listener class
- KotlinCommand base class for commands that need their own file
- Scheduler helpers: runLater, runTimer, runAsync
- Config helpers: saveLocation, getLocation, config, setConfig
- Message helpers: msg, broadcastMsg, colorize with & color code support
Installation
Add this to your
build.gradle.kts:
Code (Kotlin):
repositories
{
maven
(
"https://jitpack.io"
)
}
dependencies
{
implementation
(
"com.github.kolerz:kframework:1.0.0"
)
}
Important: use
shadowJar to bundle the framework into your plugin jar, otherwise it won't load on the server.
Usage
Main class
Code (Kotlin):
class MyPlugin
: KotlinFramework
(
)
{
override
fun onStart
(
)
{
registerCommand
(
"heal", playerOnly
=
true
)
{
player
!!.
health
=
20.0
reply
(
"&aHealed!"
)
}
registerCommand
(
"broadcast", permission
=
"myplugin.broadcast"
)
{
requireArgs
(
1,
"/broadcast <message>"
)
{
broadcastMsg
(
"&8[&cBroadcast&8] &f${args.joinToString("
")}"
)
}
}
registerListener
{
on
<PlayerJoinEvent
>
{
player.
msg
(
"&aWelcome, &f${player.name}&a!"
)
}
on
<PlayerDeathEvent
>
(priority
= EventPriority.
HIGHEST
)
{
deathMessage
(
null
)
}
}
runTimer
(0L, 20L
* 60L
* 5L
)
{
broadcastMsg
(
"&eRemember to vote!"
)
}
}
}
Separate command class
Code (Kotlin):
class SpawnCommand
: KotlinCommand
(playerOnly
=
true
)
{
override
fun CommandContext.
execute
(
)
{
val spawn
= getLocation
(
"spawn"
)
?: run
{
reply
(
"&cSpawn is not set!"
)
return
}
player
!!.
teleport
(spawn
)
reply
(
"&aTeleported!"
)
}
}
API
KotlinFramework
- registerCommand(name, playerOnly, permission) { } — inline command
- registerCommand(name, executor) — class-based command
- registerCommands(vararg Pair) — multiple commands at once
- registerListener { } — inline event registration
- registerListeners(vararg Listener) — multiple listener classes
Extensions
- String.colorize() — converts & to §
- CommandSender.msg(message) — colored message
- CommandSender.requirePlayer { } — ensures sender is a player
- broadcastMsg(message) — broadcast to all players
- runLater(delay) { } — delayed task
- runTimer(delay, period) { } — repeating task
- runAsync { } — async task
- saveLocation(path, location) — save location to config
- getLocation(path) — read location from config
- setConfig(path, value) — write and save config value
- config(path, default) — read config value
CommandContext
- sender — the CommandSender
- player — the Player (nullable)
- args — arguments array
- reply(message) — send colored message to sender
- requireArgs(min, usage) { } — minimum argument check
Requirements
- Paper 1.21+
- Java 21+
- Kotlin 2.x
Source
GitHub:
https://github.com/kolerz/kframework
License
MIT — free to use in any project.