Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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 result object whose item-ID field is named id. Older tutorials (and packs written before this changed) use a field called item instead. 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 use id.

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 count to 4 and /reload. Now one grid of nuggets gives you four helmets. Silly, but it proves the field works. Set it back to 1 when 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 named planks, 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 a pattern and no result. 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 type names that start with crafting_special_ (and there’s a crafting_decorated_pot too). 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 doLimitedCrafting game rule; then only unlocked recipes can be crafted. You can hand out a recipe with the /recipe give command, 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:

  1. Save all three files.
  2. In your test world, run /reload (typed in chat, with the slash) to re-read the pack.
  3. 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 #tag ingredient 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_tag and 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.