Wiki 9Minecraft Wiki 9Minecraft

Block Format History and Schema Versions

How custom block JSON schemas evolved from early experimental toggles to modern stable releases.

5Sections
2Code examples
3Known errors

The `format_version` field at the top of a behavior pack block file tells Minecraft which schema rules to use when parsing your block. Understanding the history of these versions is essential when updating older add-ons, reading legacy tutorials, or migrating blocks away from retired experimental toggles toward the modern Scripting API.

How format_version Controls Block Parsing

Every custom block JSON file in a behavior pack begins with a `format_version` string. This string does not necessarily have to match the exact version of Minecraft you are running, nor does it need to match the `min_engine_version` in your pack's `manifest.json`. Instead, it acts as a contract with the game's JSON parser, dictating which components are valid, how their fields are structured, and whether experimental world toggles are required to load the block.

When Mojang updates a block component—such as renaming a field or changing a boolean into an object—they gate that change behind a newer `format_version`. This ensures backward compatibility so older add-ons continue to function when players update their game, unless the underlying experimental feature itself is completely removed from the engine.

Format EraKey CharacteristicsCurrent Status
1.16.0Basic data-driven blocks; geometry and textures defined in RP `blocks.json`.Legacy, still parses for simple blocks
1.16.100 - 1.18.xHoliday Creator Features era; introduced permutations, custom geometry, and JSON events.Deprecated; JSON events removed in 1.20.80+
1.19.40 - 1.19.80Great component renaming; components stabilized out of experimental toggles.Stable, widely supported
1.20.20 - 1.20.60Built-in traits (`minecraft:placement_direction`), geometry bone visibility.Stable
1.20.80 - 1.21.x+JSON events removed; `minecraft:custom_components` links to Script API.Current standard

The 1.16.100 Experimental Era

Custom blocks gained most of their flexibility in the 1.16.100 update under the Holiday Creator Features experimental toggle. Prior to this, custom blocks were limited to simple unit cubes whose textures and render methods had to be registered inside the resource pack's root `blocks.json` file. Format version `1.16.100` moved visual definitions like `minecraft:geometry` and `minecraft:material_instances` directly into the behavior pack file.

This era also introduced block states, permutations, and an event system driven entirely by JSON (`minecraft:on_interact`, `minecraft:on_step_on`, and `minecraft:on_player_placing`). Many older code examples online still show this syntax. However, the JSON event architecture was never stabilized and has since been completely stripped from modern versions of Bedrock.

BP/blocks/legacy_crate.json
{
  "format_version": "1.16.100",
  "minecraft:block": {
    "description": {
      "identifier": "wiki:legacy_crate"
    },
    "components": {
      "minecraft:destroy_time": 2.0,
      "minecraft:explosion_resistance": 5.0,
      "minecraft:unit_cube": {},
      "minecraft:material_instances": {
        "*": {
          "texture": "legacy_crate_tex",
          "render_method": "opaque"
        }
      }
    }
  }
}

The 1.19.40 and 1.19.50 Stabilization Wave

During the 1.19 cycle, Mojang began moving block components out of experimental toggles and into the base game. Rather than keeping the 1.16.100 names as-is, many components were redesigned for clarity and consistency before being locked in as stable features. If you change a block's `format_version` from `1.16.100` to `1.19.40` or `1.19.50` without updating the component names, the block will fail to parse.

For example, `minecraft:destroy_time` became `minecraft:destructible_by_mining`, and `minecraft:explosion_resistance` became `minecraft:destructible_by_explosion`. The old `minecraft:unit_cube` component was retired in favor of using the standard block geometry identifier `minecraft:geometry.full_block` inside the `minecraft:geometry` component. Additionally, custom block properties inside the `description` block were standardized under the `states` key.

Legacy Component (1.16.100)Modern Replacement (1.19.40+)Notes
minecraft:destroy_timeminecraft:destructible_by_miningNow uses `seconds_to_destroy` inside an object or a boolean
minecraft:explosion_resistanceminecraft:destructible_by_explosionUses `explosion_resistance` field inside an object or a boolean
minecraft:block_light_emissionminecraft:light_emissionTakes an integer from 0 to 15 instead of a float from 0.0 to 1.0
minecraft:block_light_absorptionminecraft:light_dampeningTakes an integer from 0 to 15
minecraft:entity_collisionminecraft:collision_boxUses `origin` and `size` arrays matching geometry coordinates
minecraft:pick_collisionminecraft:selection_boxUses `origin` and `size` arrays matching geometry coordinates
minecraft:unit_cubeminecraft:geometryUse identifier `minecraft:geometry.full_block` in `1.20.60+`

Traits and Geometry Updates in 1.20

Across the 1.20 updates, the block format gained quality-of-life features that reduced repetitive boilerplate. In `1.20.20`, block traits were introduced under the `description` object. Traits like `minecraft:placement_direction` and `minecraft:placement_position` automatically inject standard cardinal, facing, or vertical-half states onto a block without requiring an external script or placement event to read the player's rotation.

The `minecraft:geometry` component also expanded during this period. Instead of creating multiple separate `.geo.json` files to toggle parts of a model on and off across permutations, creators can now define `bone_visibility` directly inside the `minecraft:geometry` component using booleans or Molang expressions, alongside the built-in `minecraft:geometry.full_block` identifier.

Removal of JSON Events and 1.21+ Custom Components

The largest breaking change in block format history occurred in 1.20.80 and 1.21.0. Mojang retired the Holiday Creator Features toggle and permanently removed JSON block events, event responses (`set_block_state`, `run_command`, `decrement_stack`), and all `minecraft:on_*` trigger components from the engine. Any pack relying on those components in newer versions will log content errors and ignore the triggers.

In their place, `1.21.0` introduced `minecraft:custom_components`. Instead of writing imperative logic inside JSON, you attach a named custom component to your block or permutation and register its behavior in JavaScript using the `@minecraft/server` API during world initialization.

BP/blocks/modern_crate.json
{
  "format_version": "1.21.0",
  "minecraft:block": {
    "description": {
      "identifier": "wiki:modern_crate",
      "menu_category": {
        "category": "construction"
      },
      "traits": {
        "minecraft:placement_direction": {
          "enabled_states": ["minecraft:cardinal_direction"]
        }
      }
    },
    "components": {
      "minecraft:geometry": "minecraft:geometry.full_block",
      "minecraft:material_instances": {
        "*": {
          "texture": "modern_crate_tex",
          "render_method": "opaque"
        }
      },
      "minecraft:destructible_by_mining": {
        "seconds_to_destroy": 2.0
      },
      "minecraft:destructible_by_explosion": {
        "explosion_resistance": 5.0
      },
      "minecraft:custom_components": [
        "wiki:crate_interaction"
      ]
    }
  }
}

Which versions this applies to

Applies to all Bedrock versions from 1.16.0 through 1.21+. Modern blocks using format_version 1.21.0 and standard components require no experimental toggles.

When it does not work

What you seeWhyThe fix
[Blocks][error]-wiki:my_block | minecraft:destroy_time is not a valid componentYou bumped the file's `format_version` to `1.19.40` or higher, where the legacy `1.16.100` component names are no longer recognized by the schema parser.Replace legacy component keys with their modern counterparts, such as changing `minecraft:destroy_time` to `minecraft:destructible_by_mining`.
Block loads into the world, but `minecraft:on_interact` or `events` do nothing and throw a Content Log error.JSON block events and Holiday Creator Features were completely removed from the game engine starting in 1.20.80.Update `format_version` to `1.21.0`, add `minecraft:custom_components` to the block, and move your interaction logic into a `@minecraft/server` script using `blockComponentRegistry.registerCustomComponent`.
Block appears as an update block (dirt with 'update!' text) or fails to appear in the creative inventory.Your block file's `format_version` is set to a version higher than the `min_engine_version` specified in your behavior pack's `manifest.json`, or higher than the version of Minecraft you are currently running.Ensure `format_version` is less than or equal to your current game version, and raise `min_engine_version` in `BP/manifest.json` to at least match the features you are using (for example, `[1, 21, 0]`).

Reference, straight from the game files

Read out of the game itself, so the ids match the version you are building for.