Skip to main content
The NBTItem class provides access to vanilla and custom NBT tags on ItemStacks. It extends NBTCompound and implements ReadWriteItemNBT.
The NBTItem class is deprecated. Use the modern NBT.modify() syntax instead, which is up to 400% faster and provides fewer ways to mess up code.

Constructor

NBTItem(ItemStack item)
constructor
Creates a new NBTItem from an ItemStack. The ItemStack will be cloned.
ItemStack sword = new ItemStack(Material.DIAMOND_SWORD);
NBTItem nbtItem = new NBTItem(sword);
NBTItem(ItemStack item, boolean directApply)
constructor
Creates a new NBTItem with optional direct application mode.
ItemStack sword = new ItemStack(Material.DIAMOND_SWORD);
NBTItem nbtItem = new NBTItem(sword, true);
nbtItem.setString("CustomTag", "Value");
// Changes automatically applied to original sword

Core methods

getItem

getItem()
ItemStack
Returns the modified ItemStack with all NBT changes applied.
NBTItem nbtItem = new NBTItem(sword);
nbtItem.setString("owner", "Steve");
nbtItem.setInteger("level", 5);

ItemStack modifiedSword = nbtItem.getItem();

hasNBTData

hasNBTData()
boolean
Returns true if the item has NBT data. This should be checked before calling methods like remove.
NBTItem nbtItem = new NBTItem(sword);
if (nbtItem.hasNBTData()) {
    String owner = nbtItem.getString("owner");
}

hasCustomNbtData

hasCustomNbtData()
boolean
Returns true if the item has any tags not known for this item type (custom tags only).
This method is deprecated. In Minecraft 1.20.5+, there are no vanilla tags, so this behaves the same as hasNBTData().
NBTItem nbtItem = new NBTItem(sword);
if (nbtItem.hasCustomNbtData()) {
    Common.log("Item has custom NBT tags");
}

NBT application methods

applyNBT

applyNBT(ItemStack item)
void
Applies stored NBT tags to the provided ItemStack.
This will completely override the current item’s ItemMeta. To preserve original NBT tags, use mergeNBT() or mergeCustomNBT() instead.
NBTItem template = new NBTItem(new ItemStack(Material.DIAMOND_SWORD));
template.setString("owner", "Steve");
template.setInteger("level", 10);

ItemStack newSword = new ItemStack(Material.DIAMOND_SWORD);
template.applyNBT(newSword);

mergeNBT

mergeNBT(ItemStack item)
void
Merges all NBT tags to the provided ItemStack, preserving existing tags.
NBTItem source = new NBTItem(enchantedSword);
source.setString("CustomTag", "Value");

ItemStack target = new ItemStack(Material.DIAMOND_SWORD);
source.mergeNBT(target); // Preserves existing NBT on target

mergeCustomNBT

mergeCustomNBT(ItemStack item)
void
Merges only custom (non-vanilla) NBT tags to the provided ItemStack.
NBTItem source = new NBTItem(customItem);

ItemStack target = player.getInventory().getItemInMainHand();
source.mergeCustomNBT(target); // Only custom tags merged

clearCustomNBT

clearCustomNBT()
void
Removes all custom (non-vanilla) NBT tags from the NBTItem.
In Minecraft 1.20.5+, this clears all NBT data since there are no vanilla tags.
NBTItem nbtItem = new NBTItem(sword);
nbtItem.clearCustomNBT();
ItemStack cleanSword = nbtItem.getItem();

ItemMeta integration

modifyMeta (BiConsumer)

modifyMeta(BiConsumer<ReadableNBT, ItemMeta> handler)
void
Provides safe access to the ItemMeta of the internal ItemStack.Supported operations:
  • Any get/set method of ItemMeta
  • Any getter on NBTItem
All changes made to the NBTItem during this scope will be reverted at the end.
NBTItem nbtItem = new NBTItem(sword);
nbtItem.modifyMeta((nbt, meta) -> {
    meta.setDisplayName("§6Legendary Sword");
    
    List<String> lore = new ArrayList<>();
    lore.add("§7Owner: " + nbt.getString("owner"));
    lore.add("§7Level: " + nbt.getInteger("level"));
    meta.setLore(lore);
});

modifyMeta (typed)

modifyMeta(Class<T> type, BiConsumer<ReadableNBT, T> handler)
void
Provides safe access to a specific ItemMeta type.
NBTItem nbtItem = new NBTItem(skull);
nbtItem.modifyMeta(SkullMeta.class, (nbt, meta) -> {
    meta.setOwner(nbt.getString("skullOwner"));
});

Static conversion methods

convertItemtoNBT

convertItemtoNBT(ItemStack item)
NBTContainer
Converts an ItemStack to NBTContainer with all its data (Material, Damage, Amount, Tags).
ItemStack sword = new ItemStack(Material.DIAMOND_SWORD);
NBTContainer container = NBTItem.convertItemtoNBT(sword);

convertNBTtoItem

convertNBTtoItem(NBTCompound comp)
ItemStack
Converts an NBTCompound back to an ItemStack.
NBTContainer container = NBTItem.convertItemtoNBT(sword);
ItemStack reconstructed = NBTItem.convertNBTtoItem(container);

convertItemArraytoNBT

convertItemArraytoNBT(ItemStack[] items)
NBTContainer
Converts an ItemStack array to NBTContainer with all data.
This is a custom implementation and won’t work with vanilla code (Shulker content, etc.)
ItemStack[] inventory = player.getInventory().getContents();
NBTContainer container = NBTItem.convertItemArraytoNBT(inventory);

convertNBTtoItemArray

convertNBTtoItemArray(NBTCompound comp)
ItemStack[]
Converts an NBTCompound back to an ItemStack array.
NBTContainer saved = NBTItem.convertItemArraytoNBT(inventory);
ItemStack[] restored = NBTItem.convertNBTtoItemArray(saved);

Usage patterns

Basic NBT manipulation

ItemStack sword = new ItemStack(Material.DIAMOND_SWORD);
NBTItem nbtItem = new NBTItem(sword);

// Set custom data
nbtItem.setString("owner", "Steve");
nbtItem.setInteger("level", 5);
nbtItem.setBoolean("legendary", true);

// Get modified item
ItemStack modifiedSword = nbtItem.getItem();
player.getInventory().addItem(modifiedSword);

Reading NBT data

ItemStack item = player.getInventory().getItemInMainHand();
NBTItem nbtItem = new NBTItem(item);

if (nbtItem.hasNBTData()) {
    String owner = nbtItem.getString("owner");
    int level = nbtItem.getInteger("level");
    
    player.sendMessage("Owner: " + owner);
    player.sendMessage("Level: " + level);
}

Direct apply mode

ItemStack sword = player.getInventory().getItemInMainHand();
NBTItem nbtItem = new NBTItem(sword, true);

nbtItem.setInteger("uses", nbtItem.getInteger("uses") + 1);
// Changes automatically applied to original sword

Working with ItemMeta

NBTItem nbtItem = new NBTItem(sword);
nbtItem.setString("rarity", "legendary");

nbtItem.modifyMeta((nbt, meta) -> {
    String rarity = nbt.getString("rarity");
    meta.setDisplayName("§6[" + rarity.toUpperCase() + "] Sword");
});

ItemStack result = nbtItem.getItem();

See also

  • NBTEntity - Work with entity NBT data
  • NBTBlock - Store NBT data at block locations
  • NBTFile - Read/write NBT data from files

Build docs developers (and LLMs) love