Chapter 15 — Recipes
What You’ll Build
Way back in Chapter 9 you wrote a single recipe: a chainmail helmet crafted from iron nuggets. It worked, it showed up in the recipe book, and then you moved on. That recipe used just one of the many kinds of recipe Minecraft understands. This chapter opens the whole box.
By the end you’ll be able to add almost any kind of recipe to the pack you started in Chapter 9,
your mypack pack. You’ll write shaped and shapeless crafting recipes; smelting,
blasting, smoking, and campfire cooking recipes (with their own cook times and
experience rewards); stonecutting recipes; both kinds of smithing recipe; the special
transmute and dye recipes; and you’ll make any of them accept “any kind of wood” or “any
copper ore” by feeding them the registry tags you learned in Chapter 14. You’ll also learn how to
remove a vanilla recipe you don’t want, and how to control where your recipes appear in the recipe
book.
This chapter extends the mypack pack from Chapter 9 and uses the test world you set up in Chapter
8. It assumes you know the recipe/ folder and the shaped recipe from Chapter 9, and registry tags
(#namespace:path) from Chapter 14.
Modern Minecraft Every recipe in this chapter puts its output in a
resultobject whose item-ID field is namedid. Older tutorials (and packs written before this changed) use a field callediteminstead. If you copy a recipe off the internet and it doesn’t load, the first thing to check is whether it says"item":where it should say"id":. Throughout this book we always useid.
Where recipes live (a quick recap)
Every recipe is a single JSON file. Your custom recipe files go in the recipe folder of your
namespace: a recipe with the ID mypack:path/to/file lives at
data/mypack/recipe/path/to/file.json inside the pack. That’s exactly where the Chapter 9 helmet
recipe sits. Vanilla’s own recipes live in the same kind of place but under the minecraft
namespace (data/minecraft/recipe/...), a fact we’ll use later in this chapter to switch one off.
Every recipe file, no matter its kind, is a JSON object with one field in common: a string called
type. The type tells the game which shape of recipe this is (shaped crafting, smelting,
stonecutting, and so on) and therefore which other fields it should expect. Get the type right and
the rest of the file follows from it. The sections below are organized one type at a time.
Shaped crafting, revisited
A shaped crafting recipe is one where the ingredients have to be arranged in a particular shape on the crafting grid. The helmet you made in Chapter 9 is one: the iron nuggets have to sit in an upside-down-U shape or the recipe won’t match. Here it is again, unchanged, so we have something to build on:
mypack/data/mypack/recipe/chainmail_helmet.json
{
"type": "minecraft:crafting_shaped",
"category": "equipment",
"pattern": [
"NNN",
"N N"
],
"key": {
"N": "minecraft:iron_nugget"
},
"result": {
"id": "minecraft:chainmail_helmet",
"count": 1
}
}
Let’s read it slowly, because the two fields that make it shaped (pattern and key) work
together as a pair.
pattern is a list of strings, one per row of the crafting grid. Each string is a row, and each
character in the string is one grid slot. The recipe above has two rows, "NNN" and "N N", so it
uses a 3-wide, 2-tall area of the grid. Every string in the list must be the same length. A row can
be 1, 2, or 3 characters wide, and you can have 1, 2, or 3 rows.
key is an object that says what each character means. Here, the single key N maps to
minecraft:iron_nugget. Any single character may be used as a key except the space character: a
space in the pattern always means “this slot must be empty.” That’s why "N N" has a real gap in the
middle: the helmet has a hole in its bottom row.
The category field is new compared to Chapter 9’s bare version. It controls which tab the recipe
shows up under in the recipe book. For crafting recipes the allowed values are equipment,
building, misc, and redstone; if you leave category out, it defaults to misc. Armor is
equipment, so the helmet sits in the equipment tab.
The result object is the output. Its id is the item the recipe makes, and the optional count
is how many you get. If you leave count out, you get 1. We’ve written "count": 1 explicitly here
just to show where it goes.
Try It! Change the result’s
countto4and/reload. Now one grid of nuggets gives you four helmets. Silly, but it proves the field works. Set it back to1when you’re done.
Grouping recipes with group
There’s one more optional field worth knowing for crafting recipes: group. It’s a plain string
identifier, and recipes that share the same group are bundled together into a single entry in the
recipe book instead of cluttering it with near-duplicates. Vanilla uses this for things like all the
different wooden planks, which share a planks group. You don’t have to use it, but it keeps a busy
recipe book tidy. (A subtle detail: if two recipes share a group but have different category
values, the game splits them back into two groups, so keep the category the same across a group.)
Shapeless crafting
A shapeless crafting recipe doesn’t care where the ingredients sit on the grid, only that they
are all present. The classic example is flint and steel: you need one iron ingot and one piece of
flint, and it doesn’t matter which slots they go in. Its type is minecraft:crafting_shapeless,
and instead of pattern/key it has a single list field called ingredients:
mypack/data/mypack/recipe/flint_and_steel.json
{
"type": "minecraft:crafting_shapeless",
"category": "equipment",
"ingredients": [
"minecraft:iron_ingot",
"minecraft:flint"
],
"result": {
"id": "minecraft:flint_and_steel",
"count": 1
}
}
The ingredients list must have at least one and at most nine entries, one for every slot in
the 3×3 grid. Each entry is one ingredient that must appear somewhere in the grid. The same
category values, the optional group, and the same result shape (id + optional count) all
work exactly as they did for shaped recipes.
Under the Hood There’s a small quirk worth knowing: if a shapeless recipe lists the same nine ingredients as a shaped recipe’s full grid, the game effectively treats it as the shaped one. You’ll almost never hit this; it’s here so the behavior doesn’t surprise you. Skippable.
Ingredients, three ways
So far every ingredient has been a single item ID like "minecraft:iron_ingot". But anywhere a
recipe asks for an ingredient, you actually have three ways to write it. This is the same in
every recipe type, so learning it once pays off everywhere.
1. A single item ID: a plain string, the form you’ve already seen:
"minecraft:iron_ingot"
2. A tag, written with a leading #. This is where Chapter 14 pays off. A #tag means “any
item in this group counts.” Remember from Chapter 14 that a registry tag is a named group of types;
#minecraft:planks is the built-in group of every plank variant. Use it as an ingredient and your
recipe accepts oak, birch, spruce, or any other plank without you listing them:
"#minecraft:planks"
3. An array of IDs: a JSON list of specific item IDs, meaning “any one of exactly these”:
["minecraft:oak_planks", "minecraft:spruce_planks"]
The difference between forms 2 and 3 is how you choose the set. A #tag borrows an existing group
(or one you defined yourself in Chapter 14) and stays in sync with it. An array spells out an exact
short list right there in the recipe. Use a tag when a sensible group already exists; use an array
when you want just two or three specific items and don’t want to make a whole tag file for them.
Here’s a shapeless recipe that uses a tag ingredient, a custom “wooden button” that accepts any plank:
mypack/data/mypack/recipe/any_plank_button.json
{
"type": "minecraft:crafting_shapeless",
"category": "redstone",
"ingredients": [
"#minecraft:planks"
],
"result": {
"id": "minecraft:oak_button",
"count": 1
}
}
And the same idea with an explicit array, accepting only oak or spruce:
mypack/data/mypack/recipe/oak_or_spruce_button.json
{
"type": "minecraft:crafting_shapeless",
"category": "redstone",
"ingredients": [
["minecraft:oak_planks", "minecraft:spruce_planks"]
],
"result": {
"id": "minecraft:oak_button",
"count": 1
}
}
Notice the array in the second file is nested inside the ingredients list: ingredients is the
outer list (one entry per grid slot), and that one entry is itself the little array of acceptable
items. In a shaped recipe you’d do the same thing inside key: a key can map to a single ID, a
#tag, or an array, just like an ingredient. The three forms are completely interchangeable
everywhere an ingredient is asked for.
What Can Go Wrong Forgetting the
#on a tag is the most common recipe mistake."minecraft:planks"(no hash) tells the game to look for an item literally namedplanks, which doesn’t exist, so the recipe fails to load."#minecraft:planks"(with hash) tells it to look for the tag. One character, big difference, and Chapter 10’s game log will report the bad recipe if you miss it.
Cooking: smelting, blasting, smoking, and campfire
Furnaces, blast furnaces, smokers, and campfires all run on recipes too. They share almost the same
shape, differing mainly in their type string and their default cook time:
minecraft:smelting— a regular furnace.minecraft:blasting— a blast furnace (ores and metal things).minecraft:smoking— a smoker (food).minecraft:campfire_cooking— a campfire.
A cooking recipe takes a single ingredient (written in any of the three ingredient forms above),
turns it into a result, and adds two optional numbers: cookingtime and experience.
Here’s a smelting recipe that turns stone bricks into cracked stone bricks:
mypack/data/mypack/recipe/cracked_stone_bricks.json
{
"type": "minecraft:smelting",
"category": "blocks",
"ingredient": "minecraft:stone_bricks",
"cookingtime": 200,
"experience": 0.1,
"result": {
"id": "minecraft:cracked_stone_bricks"
}
}
cookingtime is how long the item takes to cook, measured in ticks (the game runs 20 ticks per
second, as you learned in Chapter 7, so 200 ticks is 10 seconds). It’s optional. If you leave it
out, smelting defaults to 200 ticks, while blasting, smoking, and campfire_cooking
default to 100 ticks. Blast furnaces and smokers run hotter, so even their default is faster.
experience is how much experience the player gets when they collect the cooked item. It’s a
decimal number and it’s optional. A small detail to remember: campfires never drop experience, so an
experience field on a campfire_cooking recipe simply does nothing.
Notice what the cooking result does not have: a count. Cooking recipes always produce one
output item, so their result only ever has id (and, optionally, components, more on that
later). Adding a count here won’t help. This is different from crafting and stonecutting, where
count is allowed.
The category choices differ a little by machine. Smelting allows food, blocks, and misc
(default misc); blasting allows blocks and misc; smoking and campfire both allow only food
(default food). For campfires the category and group fields are accepted but do nothing, because
campfires have no recipe book.
Here’s a campfire example (baking a potato over a fire) showing the longer cook time vanilla uses:
mypack/data/mypack/recipe/campfire_baked_potato.json
{
"type": "minecraft:campfire_cooking",
"category": "food",
"ingredient": "minecraft:potato",
"cookingtime": 600,
"experience": 0.35,
"result": {
"id": "minecraft:baked_potato"
}
}
Stonecutting
A stonecutting recipe is the simplest of all. You put one ingredient into a stonecutter, pick the
output from the menu, and it converts instantly: no shape, no cook time, no experience. Its type
is minecraft:stonecutting, and it has just two fields you care about: an ingredient and a
result. There’s no category or group for stonecutting at all.
mypack/data/mypack/recipe/deepslate_to_stairs.json
{
"type": "minecraft:stonecutting",
"ingredient": "minecraft:cobbled_deepslate",
"result": {
"id": "minecraft:cobbled_deepslate_stairs",
"count": 1
}
}
Stonecutting result objects can carry a count, unlike cooking. That’s handy when one input
should yield several outputs.
We’ll come back to stonecutting in the Practice section, where you’ll build a small family of stonecutter recipes for block variants.
Smithing: two very different recipes
The smithing table runs two completely different kinds of recipe, and it’s important not to mix
them up. They have different type strings and do different jobs:
minecraft:smithing_transform: changes the base item into a new item. This is how a diamond axe becomes a netherite axe.minecraft:smithing_trim: decorates the base item with an armor trim, leaving it the same item with a new pattern stamped on. This is how you add a trim to a chestplate.
Both share three ingredient slots, named for where they sit in the smithing table:
template: the smithing template item (optional).base: the item being upgraded or trimmed.addition: the material being added (optional).
smithing_transform — upgrading an item
mypack/data/mypack/recipe/netherite_axe.json
{
"type": "minecraft:smithing_transform",
"template": "minecraft:netherite_upgrade_smithing_template",
"base": "minecraft:diamond_axe",
"addition": "#minecraft:netherite_tool_materials",
"result": {
"id": "minecraft:netherite_axe"
}
}
A smithing_transform recipe has a result, the new item it produces. The important behavior is
that the result copies the components of the base item. So if your diamond axe was enchanted and
nearly worn out, the netherite axe that comes out keeps those enchantments and that damage. The
addition here uses a #tag ingredient, so any item in the netherite_tool_materials group works.
smithing_trim — stamping a trim
mypack/data/mypack/recipe/silence_trim.json
{
"type": "minecraft:smithing_trim",
"template": "minecraft:silence_armor_trim_smithing_template",
"base": "#minecraft:trimmable_armor",
"addition": "#minecraft:trim_materials",
"pattern": "minecraft:silence"
}
The big difference: a smithing_trim recipe has no result field at all. It doesn’t make a new
item; it adds the trim’s pattern onto whatever armor went in as the base. Which trim it applies is
named by the pattern field (here, minecraft:silence). The base and addition use #tags so
the recipe works for any trimmable armor and any trim material. If you write a smithing_trim recipe
and try to give it a result, you’ve accidentally written it like a transform. They are not
interchangeable.
What Can Go Wrong The two smithing types look similar but answer different questions. Transform answers “what new item does this become?”, so it needs a
result. Trim answers “which pattern goes on this armor?”, so it needs apatternand noresult. Pick the type by the question you’re answering.
Transmute and dye: two special crafting types
Two more crafting-table recipe types do things the basic shaped/shapeless types can’t, because they carry information from the input over to the output.
crafting_transmute — change the item, keep its components
A transmute recipe (minecraft:crafting_transmute) changes one item into another while
preserving all of the input’s components. Vanilla uses it to re-dye a shulker box: you put in any
shulker box plus a dye, and out comes the recolored box with everything still inside it, because
the contents are components that get copied across.
It has three fields beyond type: an input (the item to copy), a material (an extra
ingredient consumed alongside it), and a result:
mypack/data/mypack/recipe/blue_shulker_box.json
{
"type": "minecraft:crafting_transmute",
"category": "misc",
"group": "shulker_box_dye",
"input": "#minecraft:shulker_boxes",
"material": "minecraft:blue_dye",
"result": {
"id": "minecraft:blue_shulker_box"
}
}
The input here is a #tag (any shulker box), the material is a specific dye, and the result is
the blue box, which keeps whatever the input box was holding.
crafting_dye — the armor-dyeing recipe
A dye recipe (minecraft:crafting_dye) is the special type behind dyeing leather armor and
similar items. It has a target (the item this recipe applies to), a dye ingredient (which
dyes are allowed), and a result:
mypack/data/mypack/recipe/dye_leather_horse_armor.json
{
"type": "minecraft:crafting_dye",
"category": "misc",
"group": "dyed_armor",
"dye": "#minecraft:dyes",
"target": "minecraft:leather_horse_armor",
"result": {
"id": "minecraft:leather_horse_armor"
}
}
The dye ingredient uses the #minecraft:dyes tag, so any dye works. For this recipe to match, the
item being dyed must have the dye-able minecraft:dye component, a detail we won’t go deeper on
until components get their own chapter.
What can go on a result
You’ve now seen the two optional result fields several times. Here they are collected in one place:
count: how many copies of the item the recipe produces. Allowed on crafting and stonecutting and smithing-transform results; defaults to 1. Not used on cooking results, which always make exactly one item.components: extra data attached to the resulting item, like a custom name, enchantments, or what’s stored inside it.
We won’t unpack components fully here; they get their whole own chapter (Chapter 21). For now, just know the field exists and where it goes. A result with components looks like this in outline:
"result": {
"id": "minecraft:diamond_sword",
"count": 1,
"components": { }
}
Under the Hood A few crafting recipes are not data-driven at all — things like copying a written book or a map, or dyeing armor with several dyes at once. Those use built-in
typenames that start withcrafting_special_(and there’s acrafting_decorated_pottoo). You can’t really author these yourself; they exist so that, if you ever turn off the vanilla data pack, you can switch the built-in recipes back on one by one. You won’t need them for your own recipes. Skippable.
Removing a vanilla recipe
Sometimes you want to make an existing recipe go away instead of adding one. Maybe your pack replaces wooden swords with something custom and you don’t want players crafting the plain one.
The trick relies on how packs overlap. The rule is simple: data packs that load later, with
a recipe file at the same resource location, replace the existing recipe. Vanilla’s wooden-sword
recipe lives at data/minecraft/recipe/wooden_sword.json. If your pack contains a file at that
exact same path (under the minecraft namespace, not mypack), your version wins, because your
pack loads after the built-in vanilla pack.
So to disable the wooden sword recipe, put a file at the matching path that defines a recipe which can never be crafted: for example one whose ingredient is an item the player can’t reasonably get, or simply a different, harmless recipe. The cleanest approach players use is to overwrite it with a recipe that produces something trivial. Here’s an override that turns the wooden-sword slot into a recipe requiring a barrier block (a block normal players never have):
mypack/data/minecraft/recipe/wooden_sword.json
{
"type": "minecraft:crafting_shapeless",
"category": "misc",
"ingredients": [
"minecraft:barrier"
],
"result": {
"id": "minecraft:wooden_sword",
"count": 1
}
}
Because this file sits at vanilla’s resource location and your pack loads later, it replaces vanilla’s wooden-sword recipe. The original recipe is gone; only your (effectively uncraftable) version remains.
Good to Know Overriding a recipe at its resource location, as shown here, is the supported way to take a vanilla recipe out of play: same path, later pack wins. There’s no separate “delete this recipe” or empty-file syntax to learn; the override-with-a-dummy recipe is the clean, intended approach.
Modern Minecraft A recipe being in the game and a recipe being unlocked in your recipe book are two separate things. Players can craft any loaded recipe whose ingredients they hold, whether or not it’s been “discovered,” unless a world turns on the
doLimitedCraftinggame rule; then only unlocked recipes can be crafted. You can hand out a recipe with the/recipe givecommand, but most packs let advancements unlock recipes automatically; that’s a Chapter 19 topic.
Practice: a stonecutter for custom block variants
Time to build something. Imagine mypack adds a decorative theme based on polished blackstone,
and you want the stonecutter to offer a tidy little family of cuts from a single block of polished
blackstone bricks. Stonecutting is perfect for this: one input, many possible outputs, instant
conversion.
Make three stonecutting recipes. Each takes minecraft:polished_blackstone_bricks and produces a
different variant.
mypack/data/mypack/recipe/blackstone_brick_slab.json
{
"type": "minecraft:stonecutting",
"ingredient": "minecraft:polished_blackstone_bricks",
"result": {
"id": "minecraft:polished_blackstone_brick_slab",
"count": 2
}
}
mypack/data/mypack/recipe/blackstone_brick_stairs.json
{
"type": "minecraft:stonecutting",
"ingredient": "minecraft:polished_blackstone_bricks",
"result": {
"id": "minecraft:polished_blackstone_brick_stairs",
"count": 1
}
}
mypack/data/mypack/recipe/blackstone_brick_wall.json
{
"type": "minecraft:stonecutting",
"ingredient": "minecraft:polished_blackstone_bricks",
"result": {
"id": "minecraft:polished_blackstone_brick_wall",
"count": 1
}
}
Notice the slab recipe produces a count of 2: one brick block cuts into two slabs, which matches
how Minecraft normally trades blocks for slabs. The stairs and wall give one each.
Now load it:
- Save all three files.
- In your test world, run
/reload(typed in chat, with the slash) to re-read the pack. - Open a stonecutter, place a polished blackstone brick block in it, and you should see all three cuts offered. Pick one.
Figure (to be captured). a stonecutter menu showing the three polished-blackstone-brick variants — slab, stairs, and wall — offered from a single input block
Try It! Give one of your stonecutting recipes a
#tagingredient instead of the single block ID. If you made a custom tag in Chapter 14 that groups several “brick”-style blocks, point the recipe at#mypack:your_tagand a single stonecutter recipe will now accept any of them.
What Can Go Wrong
You wrote "item" instead of "id" in the result. This is the number-one recipe bug, especially
when copying older tutorials. The modern field name is id. A recipe with "item": in its result
won’t load; Chapter 10’s game log will flag it on /reload.
You put a count on a cooking result. Smelting, blasting, smoking, and campfire results take only
id (and optional components), never count. They always make one item. If you expected a
cooking recipe to output a stack, that isn’t how cooking works.
You forgot the # before a tag. "#minecraft:planks" is the tag (any plank);
"minecraft:planks" (no hash) is read as an item literally named “planks,” which doesn’t exist, so
the recipe silently fails to load. Whenever an ingredient should mean “any of a group,” check for the
hash.
You mixed up the two smithing types. A smithing_trim recipe must not have a result; a
smithing_transform recipe must. If your trim recipe isn’t trimming, check that you used
minecraft:smithing_trim with a pattern and no result.
What You Know Now
You can now write recipes of every major family: shaped and shapeless crafting; smelting, blasting,
smoking, and campfire cooking (with cook times and experience); stonecutting; both smithing_transform
and smithing_trim; and the special crafting_transmute and crafting_dye types. You know the three
ways to write any ingredient (a single ID, a #tag that borrows a Chapter-14 group, or an array of
IDs) and that those forms are interchangeable everywhere. You can set a recipe’s category and
group to place it neatly in the recipe book, put a count on the results that allow one, and even
remove a vanilla recipe by overriding its file path. You used all of this to give mypack a stonecutter
family for custom block variants. The one thing we deferred, the components you can attach to a
result, gets its own chapter soon, when you learn what data components really are.