Skip to main content


ยท 5 min read

Features, improvements and fixes. Strongly recommended for multi-compiler users.

Updates available

There are patches available for this release. Please update to 6.6.9.

Read the release notes on

๐Ÿšจ Breaking: bud.entry no longer parses files as globsโ€‹

You can use bud.glob if you have need for this.


export default async bud => {
bud.entry(`app`, await bud.glob(`@src/*.{js,css}`))

๐Ÿšจ Breaking: Built-in extension keys are normalizedโ€‹

@roots/bud-extensions/cdnAdds remote import functionalitybud.cdn
@roots/bud-extensions/esmAdds ESM support functionalitybud.esm
@roots/bud-extensions/clean-webpack-pluginCleans output directory on build
@roots/bud-extensions/copy-webpack-pluginCopies assets (used by bud.assets)
@roots/bud-extensions/fix-style-only-entrypointsRemoves JS output from entrypoints which only contain CSS
@roots/bud-extensions/html-webpack-pluginHTML functionality (used by bud.template)
@roots/bud-extensions/interpolate-html-webpack-pluginAdds create-react-app-like template variable support for HTML files
@roots/bud-extensions/mini-css-extract-pluginOptimized CSS loading
@roots/bud-extensions/webpack-define-pluginDefines variables which can be used in the application (used by bud.define)
@roots/bud-extensions/webpack-hot-module-replacement-pluginAdds HMR support
@roots/bud-extensions/webpack-manifest-pluginEmits manifest.json
@roots/bud-extensions/webpack-provide-pluginProvides import(s) globally to the application

If you were using one of these labels directly, you'll need to update it. The upshot of this is that your editor will likely not only tell you that it's wrong but also offer the new key as a suggestion.

โœจ Use package signifiers with bud.extensions.add and bud.useโ€‹

Very convenient! Works for webpack plugins or bud.js extensions.

export default async bud => {
export default async bud => {
await bud.extensions.add('browsersync-webpack-plugin')

This will only work if the plugin/extension is the default export.

โœจ Expand all env valuesโ€‹

Variables sourced from .env files in the path to the project are now interpolated using env-expand. Previously, only the project directory would be expanded.

If you have an unescaped string that causes the expansion to fail the error will be caught.

โœจ Better support for hot reload when using multi-compilerโ€‹

Each bud.js instance's entrypoints are now registered with @roots/bud-client/hot. This helps to prevent conflicts with reloaded modules when using multiple bud instances.

Some notes:

  • Each instance now declares each previous instance as a dependency. This allows the bud.runtime to work even when using multiple instances.
  • If you are using bud.runtime you will need to make sure that you are specifying single.
  • If you want to modify the instance dependencies manually, you can use the (new) build.dependencies hook. Or, specify the dependencies in the context argument passed to bud.make.
  • The bud.make docs have been updated.

Example of a custom dependsOn when setting up a child instance:

export default async bud => {
label: `example`,
basedir: bud.path(`example`),
dependsOn: [`some-other-instance`],

๐ŸŽ‰ Easier upgrades with bud upgrade commandโ€‹

Run bud upgrade to bump bud dependencies to the latest available version. You will need to run the install after the command completes. This is a new command and is not yet unit tested.


๐ŸŽ‰ @roots/bud-swc plugins are configurableโ€‹

Call bud.swc.plugins to manage @swc/core plugins. You can pass an array of plugins (as demonstrated in the swc docs) or a callback if you want to modify what's already there:

export default async bud => {
bud.swc.plugins(plugins => {
plugins.push([`swc-plugin`, {option: true}])

If you haven't tried @roots/bud-swc you should consider it. This extension is no longer considered experimental. There is a strong case to be made for it replacing @roots/bud-babel in @roots/bud-preset-recommend for version 7 of bud.js.


๐ŸŽ‰ Supports @roots/bud-emotionโ€‹

If you have @roots/bud-swc installed, @roots/bud-emotion will register emotion support with @swc/core.


๐ŸŽ‰ Option to disable CSS extractionโ€‹

Disable critical CSS extraction by calling bud.critical.extract(false). This isn't generally recommended.

@roots/bud-criticalcss remains an experimental extension.


๐Ÿฉน Fix: proxy assets load when in dev modeโ€‹

This fix requires acorn v3 and you must set a public path. You can opt-in with bud.sage.setAcornVersion('v3').

With the acorn version set to v3 assets should load when using the proxy directly in dev mode. You will still see 404 errors for the /bud/hot endpoint.

Internal changesโ€‹

Nothing is required of you, but if you're curious, here's what's changed:

When files are added or removed from a watched directory path the browser will now reload.

๐Ÿท๏ธ Typings: mapped extension optionsโ€‹

You should now get useful, accurate intellisense and typechecking when using the bud.extensions api directly.

โœจ CLI: warn when using bud.serve in a child compilerโ€‹

It warns you to move it to the parent context. For now it also does this for you since it's an understandable mistake and will result in a TypeError.

โœจ CLI: cleaner stack tracesโ€‹

There should be less duplication of emitted errors, more meaningful stack traces, and highlighting of important parts of the error message.

โš™๏ธ use nodenext to resolve node modulesโ€‹

We're using the nodenext tsc module setting. This enables top-level await for core bud.js packages ๐Ÿฅณ.

โš™๏ธ @roots/bud-api is now fully type-safeโ€‹

strict mode is enabled! We're beginning to implement runtime validation using zod.

๐Ÿงช migrate from jest to vitest (#1850)โ€‹

We switched from jest to vitest because of esm compatibility issues. It's pretty nice! Hopefully we'll be able to run unit tests on the CLI now.

โ„น๏ธ Release informationโ€‹

For more information review the diff to see what's changed.