You can manipulate an item's appearance through its client item. There is a list of vanilla modifications on the Minecraft Wiki.
Out of those, a commonly used type is Tint Sources, which allow you to change the color of the item based on predefined conditions.
There are only a handful of predefined tint sources, so let's see how to create our own.
For this example, let's register an item. If you are unfamiliar with this process, please read about item registration first.
java
public static final Item WAXCAP_BLOCK_ITEM = Registry.register(
BuiltInRegistries.ITEM,
ResourceLocation.fromNamespaceAndPath(ExampleMod.MOD_ID, "waxcap"),
new BlockItem(WAXCAP_BLOCK, new Item.Properties()
.setId(WAXCAP_BLOCK_ITEM_KEY))
);1
2
3
4
5
6
2
3
4
5
6
Make sure to add:
- A client item in
/items/waxcap.json - An item model in
/models/item/waxcap.json - A texture in
/textures/item/waxcap.png
The item should appear in-game.

As you can see, we're using a grayscale texture. Let's add some color using a tint source.
Item Tint Sources
Let's register a custom tint source to color our Waxcap item, so that when it rains, the item will look blue, otherwise it will look brown.
You'll first need to define a custom item tint source. This is done by implementing the ItemTintSource interface on a class or a record.
java
public record RainTintSource(int color) implements ItemTintSource {
public static final MapCodec<RainTintSource> MAP_CODEC = RecordCodecBuilder.mapCodec(
instance -> instance.group(
ExtraCodecs.RGB_COLOR_CODEC.fieldOf("color").forGetter(RainTintSource::color)).apply(instance, RainTintSource::new)
);
public RainTintSource() {
this(ARGB.opaque(0x00BFFF)); // Color code in hex format
}
@Override
public int calculate(ItemStack itemStack, @Nullable ClientLevel clientLevel, @Nullable LivingEntity livingEntity) {
if (clientLevel != null && clientLevel.isRaining()) {
return ARGB.opaque(color);
}
return ARGB.opaque(0xFFEFD5); // Color code in hex format
}
@Override
public @NotNull MapCodec<? extends ItemTintSource> type() {
return MAP_CODEC;
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
As this is part of the client item definition, tint values can be changed with a resource pack. So you need to define a Map Codec that's capable of reading your tint definition. In this case, the tint source will have an int value describing the color it will have when raining. We can use the built-in ExtraCodecs.RGB_COLOR_CODEC to compose our Codec.
java
public static final MapCodec<RainTintSource> MAP_CODEC = RecordCodecBuilder.mapCodec(
instance -> instance.group(
ExtraCodecs.RGB_COLOR_CODEC.fieldOf("color").forGetter(RainTintSource::color)).apply(instance, RainTintSource::new)
);1
2
3
4
2
3
4
We can then return this Codec in type().
java
@Override
public @NotNull MapCodec<? extends ItemTintSource> type() {
return MAP_CODEC;
}1
2
3
4
2
3
4
Finally, we can provide an implementation for calculate that would decide what the tint color would be. The value of color is the one coming from the resource pack.
java
@Override
public int calculate(ItemStack itemStack, @Nullable ClientLevel clientLevel, @Nullable LivingEntity livingEntity) {
if (clientLevel != null && clientLevel.isRaining()) {
return ARGB.opaque(color);
}
return ARGB.opaque(0xFFEFD5); // Color code in hex format
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
We then need to register our item tint source. This is done in the client initializer using the ID_MAPPER declared in ItemTintSources.
java
ItemTintSources.ID_MAPPER.put(ResourceLocation.fromNamespaceAndPath(ExampleMod.MOD_ID, "color"), RainTintSource.MAP_CODEC);1
Once this is done, we can use our item tint source in an client item definition.
json
{
"model": {
"type": "minecraft:model",
"model": "example-mod:item/waxcap",
"tints": [
{
"type": "example-mod:color",
"color": -16728065
}
]
}
}1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
You can observe the item color change in-game.

