Getting started
A friendly, correct-from-the-first-line walkthrough: build your first Minecraft Java data pack for 1.21+, wire a function to run on load and every tick, reload it in-game, and troubleshoot when nothing happens.
What you'll build
A tiny data pack called my_pack that prints a message once when the world loads and quietly counts every game tick. By the end you'll understand the four moving parts every pack shares: the pack.mcmeta file, a namespace, a .mcfunction, and the #minecraft:load / #minecraft:tick function tags.
This guide targets Minecraft Java Edition 1.21+, which uses singular folder names (function, not functions) and pack_format 48. If you're on an older version, see pack_format history for the right number and the plural folder names.
Step 1 β Create the folder
In your world's save directory, open the datapacks/ folder and make a new folder for your pack. On a typical singleplayer install:
.minecraft/saves/<your world>/datapacks/my_pack/
Everything else lives inside my_pack/. You can also add the pack during world creation on the "More" → "Data Packs" screen, but dropping the folder into an existing world's datapacks/ is the fastest way to iterate.
Step 2 β Write pack.mcmeta
Every pack needs exactly one file at its root: pack.mcmeta. It's a small JSON file that tells Minecraft which format your pack is written for and what to show on hover.
my_pack/pack.mcmeta
{
"pack": {
"pack_format": 48,
"description": "My first data pack"
}
}
"pack_format": 48 is the value for 1.21. The description is the text shown when you hover the pack in the list β set it to something, even trivial, so it doesn't look broken.
JSON does not allow trailing commas or comments. If Minecraft refuses your pack or drops into Safe Mode, a malformed pack.mcmeta is the usual culprit β paste it through a JSON validator.
Step 3 β Make a namespace
All of a pack's content lives under data/<namespace>/. A namespace is your project's unique prefix; use a lowercase, snake_case name that won't collide with other packs. We'll use my_pack:
my_pack/
βββ pack.mcmeta
βββ data/
βββ my_pack/ # <- your namespace
βββ function/ # .mcfunction files go here (singular folder!)
Files you place here get an ID of the form namespace:path. So data/my_pack/function/hello.mcfunction becomes the function my_pack:hello. Valid namespace/path characters are a-z 0-9 _ - . (and / in the path only).
Reserve the special minecraft namespace only for overriding vanilla files and for the load/tick tag files in Step 5. Keep your content under your own namespace.
Step 4 β Write your first function
A function is a plain-text .mcfunction file: one command per line, run top to bottom. Create two of them β a setup message and a tick counter.
data/my_pack/function/hello.mcfunction
# Runs once when the pack loads
say My first data pack is loaded!
scoreboard objectives add my_pack.ticks dummy
data/my_pack/function/loop.mcfunction
# Runs every tick β keep tick work light!
scoreboard players add #timer my_pack.ticks 1
Lines starting with # are comments. The hello function creates a scoreboard objective; the loop function bumps a fake player counter once per tick.
Step 5 β Hook it to load & tick
Minecraft runs your functions automatically when they're listed in two special vanilla function tags: #minecraft:load (once on world load and after every /reload) and #minecraft:tick (every tick, 20 times a second). These tag files live under the minecraft namespace:
my_pack/
βββ data/
βββ my_pack/
β βββ function/
β βββ hello.mcfunction
β βββ loop.mcfunction
βββ minecraft/
βββ tags/
βββ function/
βββ load.json
βββ tick.json
data/minecraft/tags/function/load.json
{
"values": [ "my_pack:hello" ]
}
data/minecraft/tags/function/tick.json
{
"values": [ "my_pack:loop" ]
}
These are ordinary tags, so if another pack also adds to #minecraft:load, both packs' entries are kept (tags merge). See Tags for the full merge/replace rules.
Keep the tick function a thin dispatcher and put real work behind conditions β a heavy #minecraft:tick function is the number-one cause of lag in data packs.
Step 6 β Reload & test
With the pack in place, load the world and run:
/reload
/reload re-reads your functions, tags, recipes, loot tables, and more without leaving the world, then fires #minecraft:load. You should see the say message appear immediately. To run a function by hand:
/function my_pack:hello
Confirm the pack is enabled and check its load order any time with:
/datapack list
/datapack list enabled
/reload only hot-swaps the functions-and-data subset. Changes to world generation, dimensions, enchantments, damage types, and other dynamic registries are read only at world load β for those, exit and re-open the world (or restart the server).
Troubleshooting
If /reload runs but nothing happens, work down this list β the causes are almost always structural, not logical.
| Symptom | Likely cause & fix |
|---|---|
Pack doesn't appear in /datapack list | pack.mcmeta is missing, in the wrong place, or invalid JSON. It must be at the pack root, beside data/. |
| Pack loads but the function never runs | Folder is plural (functions/, tags/functions/). On 1.21+ every folder is singular β rename to function/. This is the most common mistake. |
| "Incompatible" / "made for a different version" warning | Your pack_format doesn't match the game version. It still loads if you confirm; fix the number from pack_format history. |
| Red error text on load, or Safe Mode prompt | A JSON file (often a tag or pack.mcmeta) is malformed. Fix the JSON and /reload rather than accepting Safe Mode. |
/function my_pack:hello says "Unknown function" | The file path or namespace doesn't match the ID. my_pack:hello must be data/my_pack/function/hello.mcfunction β check spelling, lowercase, and the .mcfunction extension. |
| Load function re-runs destructively on every reload | Gate initialization behind an "is-installed" check so /reload doesn't reset state you want to keep. |
Next steps
- Pack structure & pack.mcmeta β the full folder tree, every registry folder, namespaces, overlays, and the complete
pack.mcmetaschema. - Functions β commands, macros, scheduling, and structuring larger packs.
- Tags β how
#minecraft:load,#minecraft:tick, and other tags merge and order.