Vanilla Recipe Extensions [Minecraft 1.21.11 to 26.2] - mezz/JustEnoughItems GitHub Wiki

[!NOTE] Version note: This page covers Minecraft 1.21.11, 26.1.2, and 26.2.

Related pages for other README-supported versions:

Vanilla Recipe Extensions

Use vanilla category extensions when your custom recipe is still a vanilla crafting or smithing recipe, but JEI needs help displaying its ingredients or outputs.

Do not create a new custom category just to display a normal crafting recipe. Extend the vanilla category instead.

Crafting Extensions

Register crafting extensions in registerVanillaCategoryExtensions.

@Override
public void registerVanillaCategoryExtensions(IVanillaCategoryExtensionRegistration registration) {
  registration.getCraftingCategory()
    .addExtension(ColoredUpgradeRecipe.class, new ColoredUpgradeCraftingExtension());
}

Implement ICraftingCategoryExtension<R> for the recipe class.

public final class ColoredUpgradeCraftingExtension implements ICraftingCategoryExtension<ColoredUpgradeRecipe> {
  @Override
  public List<SlotDisplay> getIngredients(RecipeHolder<ColoredUpgradeRecipe> recipeHolder) {
    return recipeHolder.value().getDisplaysForJei();
  }

  @Override
  public int getWidth(RecipeHolder<ColoredUpgradeRecipe> recipeHolder) {
    return 3;
  }

  @Override
  public int getHeight(RecipeHolder<ColoredUpgradeRecipe> recipeHolder) {
    return 3;
  }
}

Return 0 width and height for shapeless recipes. For shaped recipes, return the real grid width and height.

Override setRecipe only when the default crafting layout cannot represent the recipe correctly.

Smithing Extensions

Register smithing extensions the same way.

@Override
public void registerVanillaCategoryExtensions(IVanillaCategoryExtensionRegistration registration) {
  registration.getSmithingCategory()
    .addExtension(InfusionSmithingRecipe.class, new InfusionSmithingExtension());
}

Implement ISmithingCategoryExtension<R> to provide template, base, addition, and optional output examples.

public final class InfusionSmithingExtension implements ISmithingCategoryExtension<InfusionSmithingRecipe> {
  @Override
  public <T extends IIngredientAcceptor<T>> void setTemplate(InfusionSmithingRecipe recipe, T acceptor) {
    acceptor.add(recipe.template());
  }

  @Override
  public <T extends IIngredientAcceptor<T>> void setBase(InfusionSmithingRecipe recipe, T acceptor) {
    acceptor.add(recipe.base());
  }

  @Override
  public <T extends IIngredientAcceptor<T>> void setAddition(InfusionSmithingRecipe recipe, T acceptor) {
    acceptor.add(recipe.addition());
  }

  @Override
  public <T extends IIngredientAcceptor<T>> void setOutput(InfusionSmithingRecipe recipe, T acceptor) {
    acceptor.add(recipe.getExampleResult());
  }
}

Dynamic Outputs

For outputs that depend on the ingredient currently being shown in a slot, override onDisplayedIngredientsUpdate. Use the recipe slot drawables to inspect the displayed ingredients and override the rendered output when needed.

These display overrides are for rendering. They are not searchable recipe lookup data. Make sure setRecipe or the default extension methods still expose every ingredient that should be searchable.

When To Use A Custom Category Instead

Create a custom category when:

  • The recipe is not a vanilla crafting or smithing recipe.
  • The recipe needs a machine-specific layout.
  • The recipe has multiple fluid tanks, energy bars, timers, or custom widgets.
  • The recipe type should have its own JEI tab and crafting station.