Datapack Codex

Libraries & tooling

A developer's deep dive into the data-pack ecosystem: what each library and tool actually provides, how the Smithed / Weld / Lantern-Load stack lets packs coexist, and the full develop → package → distribute workflow.

📌 Note

This page is the developer-tools deep dive. For a lighter, categorised index of references, generators, communities and creators, see the resource hub. Primary target throughout is 1.21+ (singular resource folders).

Libraries

Drop-in, namespaced data packs that provide reusable functionality. Reach for a library instead of hand-rolling anything non-trivial (raycasting, GUIs, trig, player physics) — see the advanced techniques page for the patterns they replace.

LibraryWhat it providesWhen to reach for itHome
Bookshelf (Gunivers) Modular utility suite — block, raycast, math (trig/exp/log), generation, random, health, plus vector/move helpers. Pick only the modules you need. Any general-purpose need — treat it as the standard library. docs · GitHub
Smithed libraries Actionbar, Title (coordinated shared HUD), Crafter (shared custom crafting), Custom Block, Damage (score-based damage), Item, Prevent Aggression. When you want cross-pack compatibility — a shared actionbar/title/crafter that many packs use at once. docs.smithed.dev/libraries
Iris (Aeldrion) Precision raycasting — real block AABBs, entity targeting, hit block face, micrometer distance. 1.20.3+ Accurate "what am I looking at" — guns, tools, interaction targeting. github.com/Aeldrion/Iris
AjjGUI In-game-authored item/container GUIs; 8 widget types; multiplayer- and per-player-safe menus. Interactive inventory menus without editing files. github.com/AjjMC/ajjgui
TagLib (HeDeAnTheonlyone) 463 pre-built block/entity/item/biome tags plus a "tag dereferencer" that flattens tag references into concrete entries. Through 1.21.3. Save time building categorisation tags; reference-based tag composition. github.com/HeDeAnTheonlyone/Taglib
player_motion (MulverineX) Additive player velocity — launch local/global, dashes, knockback — via a data-driven impulse enchantment. Grappling hooks, dashes, blink, knockback applied to players. github.com/MulverineX/player_motion
BlockState (Triton365) Reads full block-state data at a location via a hardcoded loot-table binary-search tree (avoids modified-loot-table conflicts; handles no-loot blocks). Reliable "what block + properties is here." github.com/Triton365/BlockState
moxlib (moxvallix) Predictable data-driven API — helpers, data (NBT array ops), math, player, string, test, TUI, dimension. Single-tick, no timers. LGPL. Data-manipulation-heavy packs that want a clean, tidy API. github.com/moxvallix/moxlib
mcfunction-logger (MulverineX) Structured logging to the server console for debugging function execution. Tracing what your functions actually did, without spamming chat. github.com/MulverineX/mcfunction-logger
💡 Best practice

For raw utilities reach for Bookshelf; for cross-pack interop reach for the Smithed libraries (they exist specifically so multiple packs can share one actionbar/title/crafter). Use Iris for precise raycasts, BlockState for block introspection, player_motion for player physics, TagLib for tags, and moxlib for data/string/math behind a clean API.

The coexistence model

The Smithed ecosystem standardises how libraries live together. Each library is namespaced, versioned, and exposes its functionality through function tags rather than plain function paths. It receives inputs via scoreboard fake-players or storage NBT, and is merged with other packs by Weld using declarative merge rules. Version resolution is built on Lantern Load (#load:load). This "call the newest versioned function via a tag" convention is exactly what lets ten packs ship the same library without clobbering each other.

LayerRole
Lantern LoadThe load-ordering foundation. Packs register in #load:load and publish a load.status score so dependencies initialise in a controlled order within the same tick — #minecraft:load alone can't guarantee this.
Function tagsA library exposes its API as a function tag (e.g. #bs.math:sin). When two versions are installed, the tag calls the newest and dedupes duplicates — so packs bundling the same dependency don't conflict.
WeldSmithed's merger. It combines multiple data/resource packs into one distributable using declarative merge rules (priorities, conditions, sources) — merging pack.mcmeta, tags and function tags cleanly. It's the engine behind Smithed-library coexistence.
SmithedThe distribution platform and dependency layer on top. Depend on a library through Smithed and Weld resolves and bundles it.

data/yourpack/function/load.mcfunction (guarding init behind a dependency)

# registered in #load:load; only init once the dependency is present
execute if score dep_pack load.status matches 1.. run function yourpack:init
💡 Best practice

Depend on libraries through the ecosystem rather than copy-pasting their code. Register in #load:load, call library APIs through their function tags (never the raw internal function path), and let Weld merge shared dependencies at build time so end users install one pack, not ten.

Tooling

The editors, generators, mergers and dev mods that make authoring bearable. None are required to run a data pack — they exist to speed up writing, validating and debugging one.

ToolPurposeURL
MisodeSchema-driven web generators for loot tables, predicates, advancements, recipes, item modifiers, worldgen, text components and pack.mcmeta. Also a Data Pack Upgrader (convert between versions) and a technical changelog / version diff, backed by mcmeta.misode.github.io
mcmeta (misode)Version-controlled archive of Minecraft's generated data & assets (1.14→latest). Branches include summary, data, data-json, assets, registries and diff, one commit per version. Powers Misode's changelog and countless tools.github.com/misode/mcmeta
WeldSmithed's data/resource-pack merger — combine multiple packs into one distributable via declarative merge rules. The engine behind library coexistence.weld.smithed.dev
MCStackerWeb builder for complex commands (summon/give/data) with a full NBT/components UI.mcstacker.net
BDEngine (Block Display Engine)Web editor/animator for display entities — build and animate models, export to a data pack (summon commands / animation functions).bdengine.app
Animated JavaBlockbench plugin that rigs and animates models, exporting a data pack + resource pack that drive display entities for animated custom models.animated-java.dev
Datapack DebuggerIn-game breakpoints via #breakpoint in .mcfunction; /breakpoint step (line-by-line), /breakpoint move (resume), /breakpoint get <key> (inspect macro args). Freezes the world like tick freeze while you inspect. Fabric, 1.21.modrinth.com/mod/datapack-debugger
DatamancerFunction profiling/benchmarking, debug lines, marker goggles, a live variable tracker, and auto-reload on file change. Fabric/Quilt, 1.20–1.21.github.com/Trivaxy/datamancer
Better SuggestionsSmarter in-game command autocomplete — registry/argument-aware suggestions.Modrinth
NBT AutocompleteAutocompletes NBT/component keys and values while typing commands.Modrinth
Spyglass / VS CodeSyntax highlighting, validation, autocomplete and linting for .mcfunction and every JSON resource; version-aware. The standard pro workflow.spyglassmc.com
📌 Note

Also useful but adjacent: mcfunction-debugger (a mod-free Debug Adapter Protocol debugger for .mcfunction — breakpoints, line-by-line, @s score inspection; GitHub), and higher-level compilers that emit data packs for large projects: JMC, PackScript, and Bolt/Beet.

⚠ Gotcha

Many external tutorials and command generators predate the 1.20.5 NBT→components migration, so their item snippets (stick{…}) are wrong on current versions. When following an older guide, validate item/component syntax against Misode or the mcmeta diff before pasting. A few tool homepages are single-page apps that resist scraping — when in doubt, the URLs above are canonical.

Component builders — the things that write the JSON for you

A data pack is a pile of small JSON files, and most of them are faster to generate than to type. These build one component at a time and hand you the file; none of them need installing.

BuilderWhat it producesWhere
MisodeThe broadest of them — loot tables, predicates, advancements, recipes, worldgen, every data-driven registry, with a version selector that matters more than most people realise.misode.github.io
Crafting Recipe GeneratorCrafting, smelting, smithing and stonecutting recipes from a visual grid. Tracks current versions and Bedrock.crafting.thedestruc7i0n.ca
MCStackerWhole commands — /give, /summon, /setblock — with every NBT and component field exposed as a form.mcstacker.net
Minecraft Text EditorText components: signs, books, /tellraw, item names and lore, written visually and emitted in the current object form.text.datapackhub.net
MinecraftJSONAnother text-component and command generator; useful as a cross-check when two tools disagree about syntax.minecraftjson.com
MC ToolboxA grab-bag of small generators covering both Java and Bedrock.mctoolbox.net
BlockbenchModels. The one component you cannot sensibly hand-write — see the bbmodel page for which format supports what.blockbench.net
BDEngineDisplay-entity builds, exported as a summon command.bdengine.app
Vanilla TweaksPrebuilt packs assembled from a menu — useful as a reference implementation to read as much as to use.vanillatweaks.net
Datapack Hub / SmithedDistribution, plus a large body of published packs to read.datapackhub.net · smithed.net
⚠ Check the version selector before you copy

Generators outlive the syntax they were written for. Anything emitting stick{…} item NBT predates the 1.20.5 component migration, and anything emitting a text component as a string containing JSON predates 1.21.5 / format 71. Both produce output that looks right and silently does nothing.

Validation and simulation

Two browser tools for the steps a generator does not cover: checking a pack you already have, and seeing what it will actually build.

ToolWhat it doesWhere
MCDDDValidates Java data packs, resource packs and Mythic server packs in the browser — nothing is uploaded. Choose a pack, choose how deeply to check, read the report. Catches the class of error this reference keeps documenting: files that fail to parse and are therefore never registered, so everything referencing them dangles silently.elkonia.com/mcddd
MCJIGDrop in a data pack and see the structure your jigsaw pools will actually generate — every placed piece as a box, to scale, in 3D. The fastest way to find out that a pool sprawls, recurses, or never places the piece you thought was the point of it.elkonia.com/mcjig
💡 A validator is not a substitute for placing the thing

Both tools read your files; neither runs the game. A pack can validate cleanly and still be wrong — a loot table can reference a tag that exists but is empty, and a jigsaw pool can be structurally valid and still build something absurd. Validate, simulate, then place it.

Develop → package → distribute

Develop

Work directly in a test world's datapacks/<yourpack>/ folder (or symlink from a git repo), and keep a dedicated flat/creative world template for fast iteration. Edit in VS Code + Spyglass for validation and autocomplete; for large projects reach for a compiler (JMC/PackScript/Beet-Bolt). Iterate with the tight loop: save → /reload → /function yourpack:test. Bind /reload plus a test function to a repeating command block or a carrot_on_a_stick for one-key testing.

Debug

First, the failures that do not announce themselves

Most data pack bugs are loud: a command errors, a number is wrong. The expensive ones are silent, and nearly all of them have the same shape — a file that fails to parse is never registered. Nothing in the world tells you. The file simply does not exist as far as the game is concerned, so everything that references it quietly does nothing.

What brokeWhat you see in gameWhat the log says
One bad value in a loot table Trades, chest pools and items that point at it all go empty at once Couldn't parse data file '…': Not a valid resource location
One old-syntax line in a function The whole function does nothing — not just that line Can't parse particle options: No key block_state in MapLike[{}]
A leading / on a command inside a .mcfunction The function is invalid and fails when it tries to run Check the log after /reload; the exact message is not recorded here
An invalid text colour The function containing it fails to load Check the log after /reload; the exact message is not recorded here

The first two are taken verbatim from production packs on 26.2; see the destination field and block particle options for the causes.

Read the log before you read your code

The game writes every load failure to its log — logs/latest.log in the game or server directory — at the moment the pack loads. Search it for your namespace right after a /reload. A parse error there names the exact file, which turns an hour of reading JSON into one line. If the log is silent and the behaviour is still wrong, the file loaded and the bug is in its logic, which is a different and much easier hunt.

The test loop

  1. Save the file.
  2. /reload — reloads data packs in place. It needs permission level 2. If a change still does not appear, rejoining the world is the fallback; some changes are only picked up on a fresh load.
  3. /datapack list — confirm the pack is actually enabled. A pack that is present but disabled looks exactly like a pack with a bug. /datapack enable reports when a name is not a valid pack.
  4. Check the log for your namespace.
  5. Run the thing: /function yourpack:test, place the structure with /place, or roll the table with /loot.

Bind /reload and your test function to a repeating command block or an item for a one-key loop.

Tools, and what each one can and cannot see

Package

Get the structure right: pack.mcmeta with the correct pack_format for your target version, data/<ns>/function/…, tags in data/<ns>/tags/…, and data/minecraft/tags/function/{load,tick}.json (or Lantern Load's #load:load). Ship a resource pack alongside when you need custom models/textures/sounds — custom items use the item_model/custom_model_data components on 1.21.4+ (or CustomModelData earlier). Combine the RP + DP so custom items actually look right; Modrinth and Smithed can bundle both. Use Weld to pre-merge library dependencies into a single distributable pack when needed.

⚠ Version differences
  • Baseline pack_format = 48 for 1.21–1.21.1.
  • Since 1.21.2–1.21.3: 57. Since 1.21.4: 61. Since 1.21.5: 71 — and it keeps climbing per release.
  • Always verify the current format against Misode / mcmeta rather than memory.

Distribute

PlatformBest for
SmithedLibrary/ecosystem packs — handles Lantern Load / Weld conventions and cross-pack compatibility.
ModrinthGeneral data-pack + resource-pack hosting with versioning and declared dependencies.
Planet Minecraft / CurseForgeBroad reach for standalone content.

Whichever platform you pick, tag supported Minecraft versions accurately, include install instructions, and ship an uninstall function so players can cleanly remove your pack.

💡 Best practice

A minimal, reliable toolchain: Misode to generate and validate JSON, VS Code + Spyglass to edit, the Datapack Debugger to troubleshoot, Bookshelf for common utilities, and Weld to bundle it all for release. See the resource hub for the wider catalogue of references and creators.

Sources