docs
Guides
Dev vs Release Builds

Dev vs Release Builds

bedrock-build has two build modes: dev (the default) and release (opt-in via --release). They're tuned for different jobs. This page covers what each mode produces, when to use which, and the small set of cases where it matters.

At a glance

dev (default)release (--release)
Sourcemapsinlinenone
Minifiednoyes
NODE_ENVunsetproduction
Bundle sizelargersmaller
Typical uselocal dev, debugging, hot reloaddistribution, CI, .mcaddon packaging

For the full pipeline, see Compiler Pipeline.

Dev mode (default)

npm run build         # dev
npm run watch         # dev
npm run deploy        # dev (unless --release)

What you get:

  • Inline sourcemaps. Runtime errors map back to your TypeScript lines, which is the difference between "crash at main.js:1:47823" and "crash at src/items/sword.ts:14".
  • No minification. The output is readable if you ever need to look at the bundled file directly.
  • NODE_ENV left unset. Any process.env.NODE_ENV check in your code (or in a dependency) sees the dev branch.

Use it for:

  • Day-to-day development.
  • Debugging a script that throws inside Minecraft (you want the sourcemap).
  • deploy --watch hot reload sessions.

Release mode (--release)

npm run release                       # bedrock-build build --release
npm run deploy -- --release           # pass --release through npm
npm run pack                          # always implies --release

What you get:

  • No sourcemaps. Smaller file, no source-mapped surface to expose.
  • Minified output via esbuild's built-in minifier.
  • NODE_ENV=production. Dependencies that check it (rare in Bedrock scripts, but possible) take their production branch.

Use it for:

  • Producing a .mcaddon for distribution. npm run pack runs release for you, so this is usually transparent.
  • A final pre-release deploy to playtest the actual shipped build, not the dev build with sourcemaps.
  • CI builds that publish or upload artifacts.

pack always implies --release. You cannot ship a dev-mode .mcaddon. The flag is rejected, and the build always runs in release mode. See Packaging a .mcaddon.

When the difference actually matters

In practice, the two cases where the mode matters:

  1. Debugging. If you're chasing a runtime error in Minecraft, you want dev mode. The inline sourcemap turns the stack trace into real file paths.
  2. Distribution. If you're producing a file for someone else to install, you want release mode. Smaller, cleaner, no debug payload.

Everything else is local iteration where the difference doesn't show up.

Performance: the minify overhead is tiny

A common worry: "isn't minification slow?" In practice, esbuild's minifier adds something like 30ms to a build that already takes 30 to 100ms. It's not a meaningful tradeoff for local dev, and it's invisible in CI.

The reason to default to dev mode isn't the perf. It's the sourcemaps. You want them on while you're working, off when you ship.

Quick reference

GoalCommand
Iterate locally with hot reloadnpm run deploy:watch
Iterate locally without deployingnpm run watch
One-shot dev buildnpm run build
One-shot release buildnpm run release
Clean release build for CInpm run release -- --clean
Produce a distribution .mcaddonnpm run pack

Related