docs
Concepts
Packs and Manifests

Packs and Manifests

Every Minecraft Bedrock add-on is built from two packs working together: a Behavior Pack (BP) and a Resource Pack (RP). Each has a manifest.json that tells Minecraft what the pack is, what version it is, and who it depends on. This page covers what each pack does, what's inside a manifest, and why create-mc-bedrock rewrites UUIDs every time it scaffolds a new project.

Behavior Pack vs Resource Pack

Bedrock splits an add-on into two halves on purpose. The split lets a single world install only the half it needs (e.g. a texture pack with no custom logic is just an RP) and keeps roles clear.

PackWhat lives here
Behavior Pack (packs/BP/)Scripts (scripts/main.js), entity behaviors, custom items, custom blocks, loot tables, recipes, trade tables, anything that affects game logic.
Resource Pack (packs/RP/)Textures, models, animations, sounds, particles, UI files, fonts, anything visual or audible.

Practically, the BP is where your TypeScript ends up after bedrock-build bundles it. The RP is where the art and audio for the same feature lives. A custom item, for example, needs JSON in the BP (defining its behavior) and a texture plus a item_texture.json entry in the RP (defining what it looks like).

The two manifest files

Both packs ship a manifest at their root:

packs/
  BP/
    manifest.json    ← describes the behavior pack
  RP/
    manifest.json    ← describes the resource pack

The compiler treats these as static assets. It copies them into dist/packs/BP/ and dist/packs/RP/ exactly as written. See Workspace Layout for the rest of the tree.

Anatomy of a manifest

A Bedrock manifest.json has four sections:

  • format_version: manifest schema version. 2 is current.
  • metadata: top-level metadata. product_type: "addon" marks this pack as a user-installable add-on.
  • header: identity. UUID, display name, version, and (for behavior packs) min_engine_version.
  • modules: what the pack contains. data (BP JSON definitions), script (the bundled JS), or resources (RP assets). Each module has its own UUID.
  • dependencies: other packs or scripting modules this pack needs. Two shapes show up here: UUID-shaped deps (pointing at the other pack) and module_name-shaped deps (pointing at @minecraft/server and friends).

A minimal behavior pack manifest

{
  "format_version": 2,
  "metadata": {
    "product_type": "addon"
  },
  "header": {
    "name": "my-addon BP",
    "description": "Generated by create-mc-bedrock",
    "uuid": "11111111-1111-1111-1111-111111111111",
    "min_engine_version": [1, 21, 80],
    "version": [1, 0, 0]
  },
  "modules": [
    {
      "type": "data",
      "uuid": "22222222-2222-2222-2222-222222222222",
      "version": [1, 0, 0]
    },
    {
      "type": "script",
      "language": "javascript",
      "entry": "scripts/main.js",
      "uuid": "33333333-3333-3333-3333-333333333333",
      "version": [1, 0, 0]
    }
  ],
  "dependencies": [
    {
      "module_name": "@minecraft/server",
      "version": "1.19.0"
    },
    {
      "uuid": "44444444-4444-4444-4444-444444444444",
      "version": [1, 0, 0]
    }
  ]
}

The last dependency entry is the cross-reference to the resource pack (see below).

A minimal resource pack manifest

{
  "format_version": 2,
  "metadata": {
    "product_type": "addon"
  },
  "header": {
    "name": "my-addon RP",
    "description": "Generated by create-mc-bedrock",
    "uuid": "44444444-4444-4444-4444-444444444444",
    "min_engine_version": [1, 21, 80],
    "version": [1, 0, 0]
  },
  "modules": [
    {
      "type": "resources",
      "uuid": "55555555-5555-5555-5555-555555555555",
      "version": [1, 0, 0]
    }
  ],
  "dependencies": [
    {
      "uuid": "11111111-1111-1111-1111-111111111111",
      "version": [1, 0, 0]
    }
  ]
}

Notice that the BP depends on the RP's header.uuid (44444444-...), and the RP depends on the BP's header.uuid (11111111-...). Each manifest names the other by UUID.

Why BP and RP must cross-reference

When a player adds the BP to a world, Minecraft reads its dependencies and auto-enables the matching RP from the same add-on. The same goes in the other direction. If the UUIDs don't match across the two manifests, the link breaks and the player has to enable each pack manually, which defeats the point of shipping them together as a single .mcaddon.

This is also why copy-pasting a manifest from another project is a classic foot-gun: you end up with two projects that share the same UUIDs, and Minecraft thinks they're the same pack.

How create-mc-bedrock regenerates UUIDs

Every time you run npx create-mc-bedrock, the scaffolder rewrites every UUID in both manifests with freshly generated v4 UUIDs. It also fixes the cross-references in one pass so the BP's dependency points at the new RP header UUID, and the RP's dependency points at the new BP header UUID. Module UUIDs are regenerated too.

Why regenerate at scaffold time, not build time? UUIDs need to be stable across builds and across machines. If they changed on every build, every commit would churn and every player's installed pack would look like a different pack on each update. Freezing them at scaffold time and committing them to git is the right tradeoff: every project gets unique UUIDs the moment it's created, and they stay put after that.

The compiler (bedrock-build) does not touch manifests. It treats them as part of the static pack content and copies them verbatim into dist/.

Where this is configured

In bedrock.config.json, the packs.bp and packs.rp fields point at the BP and RP source directories. The compiler expects to find a manifest.json at the root of each one.

Related

  • Workspace Layout for how the packs fit into the rest of the project.
  • Which source?: Microsoft Samples and Community Templates sometimes use different layouts (BP/ and RP/ directly at the root, or behavior_packs/<name>/). The scaffolder's manifest service detects all three.
  • Config schema: packs for pointing the compiler at non-default pack directories.