Fabric Modding: Creating Your First Block

This post was written for Minecraft Java 1.21.6 and Fabric Loader 0.16.14.

Minecraft is all about blocks—they shape the world, define its materials, and power everything from redstone contraptions to cozy cottages. That makes adding your own block one of the most fun and satisfying ways to start modding.

In this part of the tutorial, we’ll walk through how to add your own custom block to Minecraft using Java and the Fabric modding framework. You’ll learn how blocks are defined, registered, and made available to the game—and by the end, you’ll have a soft, chewy bubble gum block ready to place in the world. Let’s get started!

If you’ve wound up on this page, make sure you’ve read Fabric Modding: Creating Your First Item

The ModBlocks Class, and Our First Block

So like ModItems, we’ll make a separate class for handling all our block additions to the game. Like that class, we’ll also have a register method, but this time, we’ll make helper functions for setting up registry keys for the item, like last time, but also for the block:

package dev.epicbunny.strawberry;

import java.util.function.Function;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;

public class ModBlocks {

    private static Block register(
            String name,
            Function<AbstractBlock.Settings, Block> blockFactory,
            AbstractBlock.Settings settings,
            boolean shouldRegisterItem
    ) {
        // Create a registry key for the block using mod ID and block name
        RegistryKey<Block> blockKey = keyOfBlock(name);

        // Build the block with the provided settings and assign the registry key
        Block block = blockFactory.apply(settings.registryKey(blockKey));

        // Optionally create and register a BlockItem for the block
        if (shouldRegisterItem) {
            // Generate a registry key for the item using the same name
            RegistryKey<Item> itemKey = keyOfItem(name);

            // Create a new BlockItem linked to the block with its own registry key
            BlockItem blockItem = new BlockItem(
                    block,
                    new Item.Settings().registryKey(itemKey)
                            .useBlockPrefixedTranslationKey()
            );

            // Register the item with the item registry
            Registry.register(Registries.ITEM, itemKey, blockItem);
        }

        // Register the item with Minecraft's block registry.
        Registry.register(Registries.BLOCK, blockKey, block);
        
        return block;
    }

    // Build a block registry key using the mod ID and name
    private static RegistryKey<Block> keyOfBlock(String name) {
        return RegistryKey.of(
                RegistryKeys.BLOCK,
                Identifier.of(Strawberry.MOD_ID, name)
        );
    }

    // Build an item registry key using the mod ID and name
    private static RegistryKey<Item> keyOfItem(String name) {
        return RegistryKey.of(
                RegistryKeys.ITEM,
                Identifier.of(Strawberry.MOD_ID, name)
        );
    }
}

What the register method does

The register method in ModBlocks is responsible for creating and registering a new block in Minecraft. It takes four arguments that define the block’s identity, construction, and whether it should have an associated item:

  • name: The name of the block, like "bubble_gum_block". Combined with your mod ID, this becomes the full identifier (e.g., strawberry:bubble_gum_block).
  • blockFactory: This is the function that builds the block. For most basic blocks, you’ll use Block::new, but you can also use custom block classes later.
  • settings: These control the block’s behavior—how strong it is, what sounds it makes, whether it requires a tool, and so on. Think of this as the blueprint that shapes the block’s in-game properties.
  • shouldRegisterItem: A boolean that decides whether to also create and register a BlockItem (so the block shows up in inventories like the creative menu). Most blocks will want this set to true, but you can turn it off for technical blocks.

Breaking it down further

    // Build a block registry key using the mod ID and name
    private static RegistryKey<Block> keyOfBlock(String name) {
        return RegistryKey.of(
                RegistryKeys.BLOCK,
                Identifier.of(Strawberry.MOD_ID, name)
        );
    }

    // Build an item registry key using the mod ID and name
    private static RegistryKey<Item> keyOfItem(String name) {
        return RegistryKey.of(
                RegistryKeys.ITEM,
                Identifier.of(Strawberry.MOD_ID, name)
        );
    }

These helper functions generate registry keys for our blocks and their items. They work just like the key creation code we used earlier in ModItems, but now we’ve split them out into named methods. This doesn’t change how anything works—it just makes the code a little cleaner and easier to update later if we ever need to refactor how our keys are created. Whether you use this approach is up to you, but for consistency, you might want to adopt it in ModItems too.

Block block = blockFactory.apply(settings.registryKey(blockKey));
  • This creates the actual Block using the provided settings.
  • The registry key is embedded in the settings so the item knows its identity.
Registry.register(Registries.BLOCK, blockKey, block);
  • This officially adds your block to Minecraft’s global block list.
  • Now it can be placed in the world, referenced in commands, used in building, included in recipes, and behave like any other block in the game.
        // Optionally create and register a BlockItem for the block
        if (shouldRegisterItem) {
            // Generate a registry key for the item using the same name
            RegistryKey<Item> itemKey = keyOfItem(name);

            // Create a new BlockItem linked to the block with its own registry key
            BlockItem blockItem = new BlockItem(
                    block,
                    new Item.Settings().registryKey(itemKey)
                            .useBlockPrefixedTranslationKey()
            );

            // Register the item with the item registry
            Registry.register(Registries.ITEM, itemKey, blockItem);
        }

In Minecraft, blocks that players can place and pick up need an item version too. This is what BlockItem handles — it’s the item that appears in your inventory and lets you place the block in the world.

This block of code checks if shouldRegisterItem is true. If it is, we create a BlockItem (which is just an Item that knows how to place the block it’s tied to) and give it its own registry key.

Finally, we register that item in the same way we’d register any other item — adding it to Minecraft’s global item list.

If you don’t want your block to have an item form (for example, if it’s a technical or invisible block), you can skip this step by passing false to the register() method.

Small edit (6/27/2025)
I added the useBlockPrefixedTranslationKey for stylistic reasons pertaining to language files. We might explain in a future blog post, but it’s not important right now for the purposes of this specific tutorial.

Actually registering the block

Let’s finish setting up by creating the bubble_gum_block and making sure it gets loaded when the game starts. Here’s the rest of the ModBlocks class:

    public static void initialize() {
        // Called during mod initialization to register our blocks.
    }

    // Define and register bubble_gum_block with desired settings
    public static final Block BUBBLE_GUM_BLOCK = register(
            "bubble_gum_block",
            Block::new,
            AbstractBlock.Settings.create(),
            true // register an item version of the block
    );

In your main mod class, make sure you call initialize. Remember, this is a required step, or else your new block won’t be added.

ModBlocks.initialize();

Now let’s launch Minecraft again and give ourselves the block…

/give @p strawberry:bubble_gum_block

You should now see your brand-new block in the game! You won’t be able to do much with it just yet—and like before, it’ll probably appear as a purple-and-black checkered cube. That’s Minecraft’s default look for blocks with no model or texture defined.

But don’t worry—we’re just getting started. In the next steps, we’ll improve our new block (and its item form) by adding proper models, textures, a readable name, and support for creative mode tabs.

🎉 Congrats—you just added your first custom block to Minecraft!

No Comments on Fabric Modding: Creating Your First Block

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.