The WordPress core team just announced @wordpress/build, the next generation of WordPress plugin build tooling. For plugin authors who have been on @wordpress/scripts for years, the obvious question is: do I migrate now, wait, or ignore?

This post walks through what actually changes, the migration path for a real plugin, the gotchas you will hit, and when the migration is worth doing. I run the Wbcom plugins portfolio (100+ plugins) so this decision affects a lot of codebases. Here is the analysis, the migration playbook, the CI patterns, and the rollout plan we are using across the portfolio.

Why @wordpress/build Exists

@wordpress/scripts has been the default plugin build tool since 2019. It wraps webpack, babel, and a set of WordPress-specific defaults: asset file generation, block.json handling, i18n extraction, JSX support, Sass. It shipped as a single package with a CLI and has been iteratively improved since.

The issue: webpack is a legacy choice in 2026. The broader JavaScript ecosystem moved on. Vite, esbuild, swc, and Bun have been production-ready for years. Build times, bundle sizes, and dev server performance are dramatically better with modern tooling. @wordpress/scripts has added some of this incrementally but is architecturally locked into webpack.

@wordpress/build is the core team’s answer. A modern build pipeline built around esbuild or swc, with the WordPress-specific defaults preserved. The goal is faster builds, smaller bundles, better DX, without forcing plugin authors to rewrite their build configuration by hand.

The strategic context: the WordPress block editor is increasingly JavaScript-heavy, with view scripts, block bindings, the Interactivity API, and progressive hydration patterns. The slower your build pipeline, the slower your iteration loop on these features. Plugin authors building serious block editor work have been migrating to Vite and esbuild ad-hoc for two years. @wordpress/build is core’s official answer to consolidate that drift.

What Actually Changes

From a plugin author’s perspective, the changes split into four categories.

1. Faster builds

Build-time improvements are the headline feature. Modern bundlers like esbuild and swc routinely produce 10x to 100x faster cold builds than webpack for equivalent source code. In production plugin development, this translates to:

  • Cold build times dropping from tens of seconds to a handful of seconds.
  • Warm rebuild times feeling instant rather than laggy.
  • Dev server startup that does not break your flow when you restart it.
  • CI build times dropping by 60-80% for typical block-heavy plugins.

The delta is more visible on larger plugins where webpack overhead compounds. On a small plugin with two or three blocks, the improvement is real but less dramatic in absolute terms. On a 20-block plugin like BuddyPress Moderation Pro or BuddyX, you feel it on every save.

2. Smaller bundles

Modern tree-shaking and better default configuration should produce smaller output bundles for the same source code. Expect 10-20% reduction for plugins that were not aggressively optimizing their webpack config already. For plugins that had manual webpack tuning, the gap closes.

Smaller bundles matter beyond download time. The block editor parses every enqueued script, and every byte of unused code is parse and execution overhead in the editor. A leaner bundle means a faster editor for your customers.

3. Different block.json handling

This is where migration gets opinionated. @wordpress/scripts scans for block.json files with specific naming and entry-point conventions. @wordpress/build is more explicit, you declare blocks in the build configuration rather than relying on filesystem convention.

For plugins with lots of blocks, this means a configuration file that lists them. More boilerplate up front. Cleaner output and easier debugging. The benefit is that you have an explicit manifest of what is being built, which makes CI checks and audits easier.

4. Dev server and hot reload

Hot reload with @wordpress/scripts has always been workable but not great. @wordpress/build targets near-instant hot reload via the modern tooling’s native HMR. In practice, for block editor work this means changes to edit.js reflect almost immediately in the editor without a full page reload, and front-end view scripts update in place during development.

For Interactivity API work specifically, the faster HMR matters. Iterating on a data-wp-* directive used to require a full editor reload to see the effect; with the new tooling, the directive change reflects in the editor preview within a second.

Feature Comparison

A side-by-side of what changes:

Feature@wordpress/scripts@wordpress/build
Bundlerwebpack 5esbuild / swc
Cold build (medium plugin)15-30s1-3s
Warm rebuild2-5s<500ms
Block discoveryFilesystem conventionExplicit config
HMR latency1-3s<500ms
Sass supportvia sass-loadernative
JSX/TS supportvia babelnative
i18n extractionbuilt-inbuilt-in
Asset.php generationbuilt-inbuilt-in
Custom webpack loadersfull supportesbuild plugin equivalents

The Migration Path for a Real Plugin

Here is the step-by-step migration for a typical plugin.

Step 1: Audit your current build

Before you change anything, catalog what your current @wordpress/scripts setup actually does. Check package.json for:

  • Scripts (build, start, format, lint:*, test:*)
  • Dependencies (@wordpress/scripts version, any direct webpack plugins, custom loaders)
  • Webpack config overrides (webpack.config.js if you extended the defaults)
  • Babel config (.babelrc or babel.config.js if present)

Any plugin author with a custom webpack.config.js should expect the most friction during migration. If your config is a 200-line override, some of that will translate cleanly and some will need rethinking.

Document your current build time as a baseline. You will want this number to compare against the new build:

time npm run build

Step 2: Install @wordpress/build alongside @wordpress/scripts

Do not remove @wordpress/scripts on day one. Install the new package alongside and run them in parallel until your build output matches.

npm install --save-dev @wordpress/build

Add a parallel build script to package.json so you can run both:

{
  "scripts": {
    "build": "wp-scripts build",
    "build:new": "wp-build",
    "build:both": "npm run build && npm run build:new",
    "start": "wp-scripts start",
    "start:new": "wp-build --watch"
  }
}

Step 3: Create the new build configuration

Add a config file (typically wp-build.config.js or equivalent, check the @wordpress/build documentation for current naming). A minimal config declares your entry points and block locations. For a plugin with a handful of blocks, the config file is typically short:

// wp-build.config.js (illustrative)
export default {
  blocks: [
    './src/blocks/feature-grid',
    './src/blocks/testimonial',
  ],
  entries: {
    admin: './src/admin.js',
    frontend: './src/frontend.js',
  },
  outDir: './build',
  sourcemap: true,
  i18n: {
    domain: 'mytheme',
    output: './languages/mytheme.pot',
  },
};

Your exact config shape will match whatever the @wordpress/build documentation specifies at the time you migrate. Check the official reference before copying.

Step 4: Run both builds in parallel

Build with the old tool, build with the new tool, diff the output. Differences to expect:

  • Bundle filenames may differ, update your PHP enqueue logic or use the generated asset file to stay flexible.
  • Asset file contents (version hash, dependencies array) should be equivalent but may differ in ordering.
  • Sourcemap structure differs, usually not a production concern.
  • CSS output may be split differently, check that your critical CSS extraction still works.

A diff command to compare outputs structurally:

diff -r build-old/ build-new/ | head -50

Step 5: Test in WordPress

Load the plugin in WordPress and run through every interactive feature. Blocks, admin pages, REST endpoints, any JS-dependent feature. Things that break most often:

  • Missing dependencies in the asset file, blocks fail to render.
  • Different block attribute serialization, existing blocks in the database may need re-saving.
  • i18n strings not extracted, translations go missing.
  • CSS load order changes, specificity bugs appear in the editor or front-end.
  • External library imports that webpack handled implicitly may need explicit declaration.

Step 6: Run your test suite

PHPUnit for PHP, Jest for JavaScript, Playwright for end-to-end. If you have CI, run it. If you do not have CI, this is the migration that makes CI worth setting up.

A minimal CI workflow for parallel builds in GitHub Actions:

# .github/workflows/build.yml
name: Build Both Tooling
on: [push, pull_request]
jobs:
  parallel-build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm run build
      - run: npm run build:new
      - run: diff -r build/ build-new/ > build-diff.txt || true
      - uses: actions/upload-artifact@v4
        with:
          name: build-diff
          path: build-diff.txt

Step 7: Remove @wordpress/scripts and cut over

Once parallel builds produce equivalent output and the plugin works in WordPress with tests passing, remove @wordpress/scripts and rely on @wordpress/build as the single build path.

npm uninstall @wordpress/scripts

Update package.json scripts to call @wordpress/build commands, commit, tag a release.

Final package.json shape:

{
  "scripts": {
    "build": "wp-build",
    "start": "wp-build --watch",
    "format": "wp-build format",
    "lint:js": "wp-build lint-js",
    "lint:css": "wp-build lint-css",
    "test:unit": "wp-build test-unit"
  },
  "devDependencies": {
    "@wordpress/build": "^1.0.0"
  }
}

Gotchas You Will Hit

Based on the shape of the migration and common patterns in modern tooling transitions, these are the issues to anticipate:

Custom webpack loaders

If you relied on specific webpack loaders (raw-loader, svg-url-loader, a custom loader for theme-specific asset handling) you need to find the equivalent in the new tooling. Some have one-to-one replacements via esbuild plugins. Some require a rethink of how you handle that asset type.

Multiple entry points

If your plugin has multiple entry points (an admin script, a front-end script, a block editor script, separate view scripts per block) expect to declare each one explicitly. @wordpress/scripts was lenient with conventions. @wordpress/build is more explicit.

Alias imports

If you used webpack aliases (import Utils from '@/utils') the path resolution rules change. You may need to update imports or configure aliases in the new tool.

// wp-build.config.js with alias support
export default {
  alias: {
    '@': './src',
    '@components': './src/components',
  },
};

Large Sass files with complex @imports

Sass compilation works but dependency graph handling is different. Large Sass files with complex partial imports may build differently in edge cases. Test visually, do not just trust that the CSS output is valid.

Asset file dependencies

The .asset.php file that WordPress uses for dependency declaration is generated differently. Verify the generated file on a few blocks and check that the dependency list matches what your block actually needs.

HMR edge cases with block editor

Hot module replacement inside the WordPress block editor has always been tricky. The new tooling handles the common cases well, but blocks with complex state, controlled inputs, or InnerBlocks sometimes need a manual editor refresh after certain edits.

Source map paths in production

If you ship source maps to production (some teams do for debug purposes), verify the source paths in the new sourcemap output point where you expect. esbuild and webpack generate source paths slightly differently.

When to Migrate Now vs Wait

Migrate now if:

  • You are starting a new plugin, no legacy to fight.
  • Your current @wordpress/scripts setup is painfully slow and affecting your iteration speed.
  • You have CI and a test suite you trust.
  • You maintain a small number of plugins and can afford focused migration time.
  • Your team has been complaining about slow builds.

Wait if:

  • Your plugin is in a critical release window and you cannot afford unexpected build issues.
  • You rely heavily on custom webpack configuration that does not yet have a clear translation path.
  • You have a large plugin portfolio where migrating all of them is a multi-month effort, pick the plugins where the performance win is biggest and migrate those first.
  • You are on an older WordPress version, make sure your minimum WP version is one where @wordpress/build works cleanly.
  • Your plugin uses pre-1.0 features that may still change.

The Wbcom Playbook

For our 100+ plugin portfolio, the plan is:

  1. Migrate two plugins fully in the next sprint, pick ones with medium complexity and active development.
  2. Document the patterns that worked in a shared migration guide for the team.
  3. Migrate new plugins to @wordpress/build from day one going forward.
  4. Schedule legacy plugin migrations in order of build-time pain, the plugins where developers are most frustrated go first.
  5. Re-benchmark the portfolio’s total build time quarterly and track the improvement.
  6. Update internal CI templates to use @wordpress/build for new plugin scaffolds.
  7. Maintain a fallback to @wordpress/scripts for legacy plugins on older WordPress versions until they reach end-of-life.

Plugin authors with fewer plugins can do this in one focused week. Plugin authors with portfolios should plan it as a quarter-long project.

Cost-Benefit Analysis for Plugin Authors

If you are deciding whether to invest the migration time, here is the rough calculation:

Time investment per plugin: 4-8 hours for a typical plugin, 16-24 hours for a plugin with extensive webpack customization.

Time saved per developer per week on a plugin you actively work on: 30-60 minutes from faster builds and HMR, depending on how much block editor work you do.

Payback period: 2-4 weeks of active development time. Faster for teams iterating heavily on block editor features.

Indirect benefits: Smaller bundle size means faster editor experience for your customers, which translates to better reviews and lower support burden.

For a plugin under active development with a team of 2+ developers, the migration pays for itself within a month. For a plugin in maintenance mode, the math is less favorable, defer the migration until you have a feature release that justifies the touch.

The Bottom Line

@wordpress/build is the direction plugin tooling is going. Not migrating is fine for a year, maybe two. Not migrating in the three-year timeframe means your plugins will feel dated to developers who pick them up.

The migration is worth doing. Start with one plugin. Document what you learn. Share it back, the WordPress plugin developer community needs more field reports on this migration, not more hype.

If you migrate your own plugin and hit something that belongs in the gotcha list above, let me know and I will add it. The collective knowledge from a few dozen real migrations will make this a smoother transition for everyone.

Common Mistakes in the First Migration Attempt

From watching teams attempt this migration, here are the patterns that consistently waste time:

  • Migrating everything at once. Pick one plugin, migrate it fully, learn the lessons, then move to the next. Trying to migrate three plugins in parallel multiplies the debugging surface and slows everyone down.
  • Not updating PHP enqueue logic. The new bundler may produce different filenames or hashes. If your PHP code hardcodes the old filenames in wp_enqueue_script(), the front-end breaks silently. Use the generated .asset.php file to stay flexible.
  • Skipping the parallel-build period. Removing @wordpress/scripts on day one feels efficient but means you have no fallback when something breaks. Run both for a week.
  • Ignoring CSS specificity changes. Different bundlers split and order CSS differently. Specificity bugs that did not exist before can appear, especially in the block editor where multiple stylesheets cascade.
  • Not benchmarking before and after. Without numbers, you cannot prove the migration was worth it to your team or to yourself. Capture build times, bundle sizes, and dev server startup time as a baseline before changing anything.
  • Forgetting the i18n step. If your old build extracted translation strings to a .pot file, verify the new build does the same. Translations going missing is one of the easiest things to overlook because it does not break local development.

Building Your Migration Tracking Spreadsheet

If you maintain more than ten plugins, treat this as a portfolio migration. A simple tracking spreadsheet with columns for:

  • Plugin name
  • Current build time (cold and warm)
  • Current bundle size
  • Migration status (not started, in progress, complete, blocked)
  • Migration owner
  • Notes on gotchas hit
  • Post-migration build time
  • Post-migration bundle size
  • Time saved per week (estimated)

This makes it easy to communicate progress to your team, decide which plugins to migrate next, and quantify the productivity benefit at the end of the quarter.

Resources and Further Reading

  • Official @wordpress/build documentation on the WordPress Developer Resources site (when published).
  • The @wordpress/scripts deprecation notice and migration guide on make.wordpress.org/core.
  • The Gutenberg GitHub repository’s packages/build directory for current implementation details.
  • The Block Editor Handbook’s tooling section for plugin authors.
  • WordPress slack #core-js channel for real-time discussion of build tooling questions.
  • The make.wordpress.org/core tag for build-tooling for ongoing announcements.

One Final Note on Timing

The pace of tooling adoption in the WordPress ecosystem is slower than in the broader JavaScript world. Plugin authors who wait for everyone else to adopt @wordpress/build before they migrate are giving up the productivity gains for two to three years. Plugin authors who migrate early have a window to be the reference implementation that others learn from. That positioning has marketing value beyond the engineering benefit.

If you maintain a public-facing plugin that other developers learn from, leading the migration is a reputation play in addition to a productivity play. Worth the investment.