Working with Minecraft Enchantment Name Translation
The internal system uses registry keys like minecraft:sharpness or minecraft:fortune, while players see localized names that vary by language pack. Getting these two to line up reliably is one of those things that looks simple until you hit a corner case. The most common reason people look into this is plugin development, modding, or building custom enchantment management systems. The raw data lives in the game's language files and the datapack JSON structure. Each enchantment has a translation key — for example, enchantment.minecraft.sharpness — which the game resolves at runtime based on the loaded locale. If you are just trying to map IDs to names for display purposes, the straightforward approach is reading the enchantment's localizedName property from the item stack during gameplay. Most mod APIs expose this directly. In Fabric with Fabric API, you can call the method that returns the formatted name string without manually parsing any language files. For server plugins, the equivalent is usually pulling the display name from the enchants configuration or the enchantment registry itself.
When you need cross-language compatibility — say, your plugin tracks enchantments by ID but you want to show names to a French or Japanese player — the issue is that different versions of Minecraft ship different language files. A key that exists in 1.20 might not resolve the same way in 1.21, and the translation key format itself shifted slightly between Java and Bedrock editions. I ran into this exact problem when building a cross-server enchantment trading platform. Players would trade items enchanted with "Looting III," and I was storing the enchantment by its display name instead of its ID. One player on a Chinese locale server logged the enchantment as " III" while the English client expected "Looting III." The trade system rejected it every time because the string comparison failed. The fix was simple in hindsight: store every enchantment by its registry key and level, then resolve the display name only at the point of rendering. That meant switching from string-based storage to a structured format using the numeric ID and level pair. Everything after that became deterministic. For anyone doing this at scale, the practical workflow is:
- Enumerate the enchantment registry to get every available key
- Pair each key with its numeric ID from the game's constants
- Use the language file or built-in localization method to get the display name for the active locale
- Store and compare using the ID, never the string name
Reading the language files directly is possible but fragile. The files are distributed as .json in the assets folder, and the structure changes between minor updates. You can parse them, but you will spend more time maintaining the parser than you save by avoiding the built-in localization API. Unless you are working offline or on a system without direct API access, there is no reason to do it manually. There is a less obvious complication with custom enchantments. If you or a plugin adds enchantments that are not part of the vanilla registry, they may not appear in the standard translation keys at all. Some authors handle this by registering their own translation entries in a separate language file. Others skip localization entirely and hardcode names. If you are building a system that needs to account for third-party enchantments, you have to scan both the vanilla registry and any custom registries the server has loaded, then merge the results. Missing a custom enchantment from the lookup means it either shows as untranslated text or falls back to the raw key, which looks broken in a UI. Bedrock Edition adds another layer. The Bedrock format does not use the same registry structure as Java, and the enchantment data is stored differently in the NBT. If your tool needs to handle both editions, you cannot rely on Java-only APIs. The translation keys exist in a completely different path in the Bedrock assets, and some enchantments simply do not have direct equivalents across editions. Sharpness exists on both. Mending exists on both. But certain Java-exclusive enchantments like "Soul Speed" have no Bedrock counterpart, and any translation table you build will have gaps there.
Get the Full Details

For people who just want a reference list without writing code, there are community-maintained tables online that map the primary enchantments to their display names across several languages. These are usually generated by scraping the game's language files, which means they are only accurate for whatever version they were built against. Using an outdated table gives you wrong translations without any error message, which is worse than having no table at all. One more thing worth noting: the order of enchantments on a tooltip is not arbitrary. The game renders them in a specific priority order based on the enchantment category. If you are sorting them yourself for a custom interface, you need to replicate that order or the display will feel inconsistent to players who know what to expect. The priority sort is documented in the enchantment class hierarchy, but it is easy to miss if you are only looking at the registry list. The core takeaway is that localization in Minecraft is handled well by the engine itself, and fighting against it by manual string matching is where most problems come from. Keep the registry key as your source of truth, let the game resolve the name, and verify against the actual installed language pack rather than assuming what it should say.