custom crafter
custom crafter is a custom recipe plugin for PaperMC servers, and also a library (API) for defining custom recipes from your own plugin.
Define custom recipes freely from your plugin and introduce new elements into the game.
Features
- Custom recipes for vanilla items — add new recipes for existing Minecraft items.
- Custom item support — use items created by your plugin as results or materials.
- Material management commands — for server administrators managing recipe materials.
- Automatic integration — registered recipes appear in players' crafting environment without extra setup.
- Vanilla crafting continues to work unmodified.
Demo
Crafting demo video
- Place base blocks (
GOLD_BLOCK). - Craft
infinityIronBlockCore(recipe definition). - Compress an iron block into
infinityIronBlock(recipe definition). - Repeat with the same recipe.
- Repeat again.
- Extract the infinity iron block with
infinityIronBlockExtract(recipe definition).

Clone the repository and run the following command to build a demo plugin containing the recipes shown above, along with several others:
mvn -pl demo package
The resulting jar, ready to be placed in a server's plugins directory, is written to demo/target.
Supported Environments
| Custom_Crafter Version | Paper Version |
|---|---|
| 5.4.0 (latest) | 1.21.4 ~ 1.21.11, 26.1.x |
| 5.0.13 ~ 5.0.21, 5.1.0 ~ 5.3.0 | 1.21.4 ~ 1.21.11, 26.1.x |
| 5.0.0 ~ 5.0.11 | 1.21.3 |
| 4.3 (legacy) | 1.21.3 |
| 4.2 (legacy) | 1.20.1 ~ 1.20.4 |
The minimum supported Paper version rarely changes between releases, so using the latest release is recommended.
Note: custom crafter does not run on Spigot/Bukkit. Use PaperMC or a Paper fork.
Using the API
Since version 5.0.0, custom crafter also works as an API for defining and registering custom recipes from your own plugin.
Documentation
To build the documentation locally:
mvn -pl api dokka:dokka # KDoc
mvn -pl api dokka:javadoc # Javadoc
Dependency
Plugins depending on CustomCrafterAPI must list Custom_Crafter under depend in plugin.yml:
depend:
- "Custom_Crafter"
Latest version: 5.4.0 (Maven Central)
The CustomCrafter plugin is assumed to be present at runtime, so set its dependency scope to compile-time only — the same applies to the Kotlin stdlib if your plugin is written in Kotlin.
Compile-time-only scope name by build tool:
- Maven:
provided - Gradle:
compileOnly
Maven
<!-- CustomCrafterAPI -->
<dependency>
<groupId>io.github.sakaki-aruka</groupId>
<artifactId>custom-crafter-api</artifactId>
<version>5.4.0</version>
<scope>provided</scope>
</dependency>
<!-- kotlin-stdlib -->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>2.3.0</version>
<scope>provided</scope>
</dependency>
Gradle (Groovy)
dependencies {
compileOnly 'io.github.sakaki-aruka:custom-crafter-api:5.4.0'
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:2.3.0' // if using Kotlin
}
Gradle (Kotlin DSL)
dependencies {
compileOnly("io.github.sakaki-aruka:custom-crafter-api:5.4.0")
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:2.3.0") // if using Kotlin
}
Server Installation
custom crafter is written in Kotlin.
- Download the plugin jar and place the downloaded files in your
pluginsdirectory. - Start or reload the server.
- Place base blocks in a 3x3 area directly beneath a standard workbench — a standard workbench alone does not enable custom recipes. The default base block is
GOLD_BLOCK.
Code Samples
Compatibility check
Checks whether the CustomCrafterAPI version your plugin depends on is compatible with the version running on the server:
class YourPlugin : JavaPlugin() {
val dependVersion = Triple(5, 3, 0)
@Override
fun onEnable() {
if (CustomCrafterAPI.MAJOR_VERSION == dependVersion.first
&& CustomCrafterAPI.MINOR_VERSION >= dependVersion.second) {
return
}
Bukkit.pluginManager.disablePlugin(this)
}
}
Defining a recipe
A custom recipe consists of three parts:
- Material (
CMatter) — the input requirements for crafting. - Result (
ResultSupplier) — what a successful craft produces. - Recipe (
CRecipe) — combines materials, results, and shape (shaped/shapeless) for registration.
1. Materials (CMatter)
CMatter defines which item, how many, and where it must be placed. Use CMatterImpl or your own implementation of CMatter.
Accept 1 stone or 1 cobblestone:
val matter: CMatter = CMatterImpl(
name = "test-matter",
candidate = setOf(Material.STONE, Material.COBBLESTONE),
amount = 1,
anyAmount = false, // true: allow the amount to be satisfied across a stack
predicates = null // additional NBT or other conditions
)
For a simple set of candidate materials, of is shorter:
val matter: CMatter = CMatterImpl.of(Material.STONE, Material.COBBLESTONE)
2. Results (ResultSupplier)
A ResultSupplier receives the crafting context (Config) and returns the output items. Command execution can be used instead where no item result is needed.
val supplier = ResultSupplier { config ->
// 'config' holds crafting context: player, workbench, etc.
emptyList<ItemStack>()
}
Helper methods cover common cases:
// Always returns 1 stone
val supplier = ResultSupplier.single(ItemStack.of(Material.STONE))
// Scales output with the number of items crafted in one action (e.g. shift-click)
val supplier2 = ResultSupplier.timesSingle(ItemStack.of(Material.STONE))
3. Recipe (CRecipe)
CRecipeImpl combines materials and results into a registrable recipe.
val recipe: CRecipe = CRecipeImpl(
name = "test-recipe",
items = mapOf(CoordinateComponent(0, 0) to matter),
containers = null, // additional conditions, e.g. permissions
results = setOf(ResultSupplier.timesSingle(Material.STONE)),
type = CRecipe.Type.NORMAL
)
items: maps grid coordinates (CoordinateComponent(x, y)) to the requiredCMatter.type:CRecipe.Type.NORMALis a shaped recipe, where coordinates matter;CRecipe.Type.AMORPHOUSis shapeless, where coordinate values are arbitrary.
License
MIT License
Copyright (c) 2023 - 2026 Sakaki-Aruka
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
