The @wordpress/scripts package provides a collection of reusable scripts and configurations for WordPress development, eliminating the need to manage complex build tooling.
Installation
npm install @wordpress/scripts --save-dev
Requires Node.js LTS version (Active or Maintenance LTS).
Setup
Add scripts to your package.json:
{
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start",
"format": "wp-scripts format",
"lint:js": "wp-scripts lint-js",
"lint:style": "wp-scripts lint-style",
"test:unit": "wp-scripts test-unit-js"
}
}
Build Scripts
build
Builds code for production.
Features:
- Minifies JavaScript
- Optimizes CSS
- Generates source maps
- Extracts CSS from JS
- Creates asset manifests
Options:
--webpack-bundle-analyzer - Visualize bundle sizes
--webpack-copy-php - Copy PHP files to output
--webpack-no-externals - Disable externals
--source-path=src - Custom source directory
--output-path=build - Custom output directory
npm run build -- --webpack-bundle-analyzer
start
Starts development build with watch mode.
Features:
- Auto-rebuilds on file changes
- Fast incremental builds
- Development source maps
Options:
--hot - Enable Fast Refresh
--webpack-devtool - Custom source map type
--no-watch - Build once without watching
Block Development
Automatic Entry Points
Scans for block.json files and builds their scripts:
src/
├── block-one/
│ ├── block.json
│ ├── index.js
│ └── style.scss
└── block-two/
├── block.json
└── index.js
block.json:
{
"editorScript": "file:./index.js",
"style": "file:./style.scss"
}
Run npm run build and get:
build/
├── block-one/
│ ├── index.js
│ ├── index.asset.php
│ └── style-index.css
└── block-two/
├── index.js
└── index.asset.php
Custom Entry Points
wp-scripts build entry-one.js entry-two.js
Styling
Import styles in JavaScript:
// Editor-only styles
import './editor.scss';
// Frontend and editor styles
import './style.scss';
Output:
index.css - Editor styles
style-index.css - Frontend & editor styles
Code Quality
Formats code with Prettier.
Formats all supported files (JS, JSON, TypeScript, YAML).
Custom paths:
lint-js
Lints JavaScript and TypeScript with ESLint.
Auto-fix:
lint-style
Lints CSS/SCSS with Stylelint.
Auto-fix:
npm run lint:style -- --fix
lint-pkg-json
Lints package.json files.
lint-md-docs
Lints markdown documentation.
Testing
test-unit-js
Runs Jest unit tests.
Watch mode:
npm run test:unit -- --watch
Coverage:
npm run test:unit -- --coverage
Specific tests:
npm run test:unit -- MyComponent.test.js
test-e2e
Runs Puppeteer end-to-end tests.
Interactive mode:
npm run test:e2e -- --puppeteer-interactive
test-playwright
Runs Playwright tests.
Debug mode:
npm run test:playwright -- --debug
Utilities
check-engines
Verifies Node.js and npm versions.
check-licenses
Validates dependency licenses.
npm run check-licenses -- --prod --gpl2
Options:
--prod - Check production dependencies only
--dev - Check development dependencies only
--gpl2 - Validate GPL2 compatibility
--ignore=package1,package2 - Ignore specific packages
packages-update
Updates WordPress packages.
Specific version:
npm run packages-update -- --dist-tag=wp-6.0
plugin-zip
Creates a plugin zip file.
Custom root folder:
npm run plugin-zip -- --root-folder=my-plugin
Configuration
Custom Webpack Config
Create webpack.config.js:
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );
module.exports = {
...defaultConfig,
// Your customizations
};
Extending Webpack Config
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );
module.exports = {
...defaultConfig,
module: {
...defaultConfig.module,
rules: [
...defaultConfig.module.rules,
{
test: /\.svg$/,
use: [ '@svgr/webpack' ],
},
],
},
};
Custom Babel Config
Create .babelrc.js:
module.exports = {
presets: [ '@wordpress/babel-preset-default' ],
plugins: [
// Your plugins
],
};
ESLint Config
Create .eslintrc.js:
module.exports = {
extends: [ 'plugin:@wordpress/eslint-plugin/recommended' ],
rules: {
// Your custom rules
},
};
Prettier Config
Create .prettierrc.js:
module.exports = {
...require( '@wordpress/prettier-config' ),
// Your overrides
};
Environment Variables
Development
NODE_ENV=development npm start
Production
NODE_ENV=production npm run build
Custom Variables
WP_ARTIFACTS_PATH=custom/path npm run test:e2e
WordPress Integration
Enqueue Built Assets
function my_plugin_enqueue_assets() {
$asset_file = include plugin_dir_path( __FILE__ ) . 'build/index.asset.php';
wp_enqueue_script(
'my-plugin',
plugins_url( 'build/index.js', __FILE__ ),
$asset_file['dependencies'],
$asset_file['version']
);
wp_enqueue_style(
'my-plugin',
plugins_url( 'build/style-index.css', __FILE__ ),
array(),
$asset_file['version']
);
}
add_action( 'enqueue_block_editor_assets', 'my_plugin_enqueue_assets' );
<?php
return array(
'dependencies' => array(
'wp-blocks',
'wp-element',
'wp-i18n',
),
'version' => '1.0.0'
);
Debugging
Debug Build
Debug Tests
wp-scripts --inspect-brk test-unit-js --runInBand --no-cache
- Run debug command
- Open
chrome://inspect
- Click “inspect” on your process
Best Practices
- Use Default Configs - Only customize when necessary
- Keep Scripts Updated - Regular updates bring improvements
- Test Before Build - Run linters and tests before production builds
- Use Source Maps - Enable for easier debugging
- Optimize Assets - Use production builds for deployment
- Version Control - Commit
package-lock.json
- CI Integration - Run checks in continuous integration
Common Issues
Build Errors
Clear cache and rebuild:
rm -rf node_modules build
npm install
npm run build
Style Not Loading
Check import statement:
// Frontend styles
import './style.scss';
// Editor styles
import './editor.scss';
Dependencies Not Found
Ensure asset file is enqueued:
$asset_file = include 'build/index.asset.php';
wp_enqueue_script( ..., $asset_file['dependencies'], ... );
Learn More