Skip to content
Development
Skill

/wp-build-tools

Use when setting up, configuring, or debugging the JavaScript/CSS build pipeline for a WordPress plugin — @wordpress/scripts, webpack (webpack.config.js, entry points, externals), Vite, block editor asset compilation with block.json, enqueueing built assets with .asset.php

From plugin
wp-dev-skills
2819 skills1 command

Claude Code

$ npx -y skills add mralaminahamed/wp-dev-skills --skill wp-build-tools --agent claude-code

SKILL.md

wp-build-tools.SKILL.md
name: wp-build-tools
description: "Use when setting up, configuring, or debugging the JavaScript/CSS build pipeline for a WordPress plugin — @wordpress/scripts, webpack (webpack.config.js, entry points, externals), Vite, block editor asset compilation with block.json, enqueueing built assets with .asset.php dependency files, wp_enqueue_script / wp_localize_script, Sass/SCSS/PostCSS compilation, TypeScript support, register_block_type, or reusing a JS/CSS library already bundled by a host plugin (EDD, WooCommerce, Elementor). Triggers: \"npm run build fails\", \"webpack config error\", \"my script is not loading\", \"set up @wordpress/scripts\", \"enqueue my block assets\", \"why is my CSS not compiling\", \".asset.php not found\", \"how do I reuse this bundled library\", \"TypeScript in a WP plugin\", \"block.json attributes\", \"missing dependency in build\", \"wp_enqueue_script not loading\", \"externals in webpack\", \"Vite for WordPress\", \"Sass not compiling\", \"PostCSS setup\", \"build output is in the wrong folder\", \"npm ci vs npm install\", \"externalize React from my bundle\", \"wp-scripts lint-js\", \"enqueue with version hash\", \"register_block_type from PHP\". Not for: block registration logic — use the official `wp-block-development` skill."

WordPress Plugin Build Tools

> **Model note:** Config setup and `.asset.php` enqueue patterns are mechanical — `haiku` covers most cases. Debugging webpack entry-point conflicts or reusing a dependency plugin's bundled library may need `sonnet`.

Configure and operate the JS/CSS build pipeline for WordPress plugins: `@wordpress/scripts` (webpack-based), Vite alternative, asset manifest handling, and correct enqueuing with the generated `.asset.php` dependency file.

When to use

  • "Set up `@wordpress/scripts`", "configure webpack for my plugin".
  • "Build blocks and admin scripts", "compile Sass for a plugin".
  • "Why isn't my JS loading?", "fix asset enqueue with versioned hash".
  • "Switch from @wordpress/scripts to Vite".
  • "Set up separate entry points for front-end vs admin vs block editor".

**Not for:** Block registration, `block.json` structure, or Gutenberg API — use the official `wp-block-development` skill. PHP-side REST API — use `wp-rest-api`.

Method

1. Install @wordpress/scripts

npm install --save-dev @wordpress/scripts

**`package.json`:**

{
  "scripts": {
    "build":   "wp-scripts build",
    "start":   "wp-scripts start",
    "lint:js": "wp-scripts lint-js",
    "lint:css": "wp-scripts lint-style"
  }
}

Default entry point: `src/index.js` → `build/index.js` + `build/index.asset.php`.

2. Multiple entry points

Create `webpack.config.js` at plugin root to override the default entry:

const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );

module.exports = {
    ...defaultConfig,
    entry: {
        'admin':        './src/admin/index.js',
        'frontend':     './src/frontend/index.js',
        'block-editor': './src/blocks/index.js',
        'style-admin':  './src/admin/admin.scss',
    },
};

Outputs:

build/
├── admin.js          + admin.asset.php
├── frontend.js       + frontend.asset.php
├── block-editor.js   + block-editor.asset.php
└── style-admin.css   (no .asset.php for pure CSS entry)

3. Enqueue assets correctly

The `.asset.php` file contains the dependency array and a content hash — always use it.

function my_plugin_enqueue_admin_assets() {
    $asset_file = plugin_dir_path( __FILE__ ) . 'build/admin.asset.php';
    if ( ! file_exists( $asset_file ) ) return;

    $asset = include $asset_file;

    wp_enqueue_script(
        'my-plugin-admin',
        plugin_dir_url( __FILE__ ) . 'build/admin.js',
        $asset['dependencies'],  // auto-includes wp-element, wp-i18n, etc.
        $asset['version'],       // content hash — cache busted on change
        true                     // in footer
    );

    wp_enqueue_style(
        'my-plugin-admin-style',
        plugin_dir_url( __FILE__ ) . 'build/style-admin.css',
        [],
        $asset['version']
    );

    // Pass PHP data to JS
    wp_localize_script( 'my-plugin-admin', 'myPluginData', [
        'ajaxUrl' => admin_url( 'admin-ajax.php' ),
        'nonce'   => wp_create_nonce( 'my_plugin_action' ),
        'apiUrl'  => rest_url( 'my-plugin/v1/' ),
    ] );
}
add_action( 'admin_enqueue_scripts', 'my_plugin_enqueue_admin_assets' );

For block assets registered via `block.json` — do NOT manually enqueue; WP handles it:

register_block_type( __DIR__ . '/build/my-block' ); // reads block.json automatically

4. Sass / PostCSS

`@wordpress/scripts` supports Sass out of the box (via webpack sass-loader). No extra config needed for `.scss` files imported in JS:

// src/admin/index.js
import './admin.scss';

For standalone `.scss` entry (CSS-only build):

// webpack.config.js entry
entry: {
    'admin-styles': './src/admin/admin.scss',
}

Output: `build/admin-styles.css` (no `.asset.php` generated for pure CSS entries — hardcode version or use `filemtime()`).

PostCSS config (`postcss.config.js`) is picked up automatically if present:

module.exports = {
    plugins: {
        autoprefixer: {},
        'postcss-custom-properties': {},
    },
};

5. Vite alternative

For non-block plugins where `@wordpress/scripts` dependency auto-detection isn't needed:

npm install --save-dev vite @vitejs/plugin-legacy

**`vite.config.js`:**

import { defineConfig } from 'vite';
import legacy from '@vitejs/plugin-legacy';

export default defineConfig( {
    plugins: [ legacy( { targets: [ 'defaults', 'ie >= 11' ] } ) ],
    build: {
        outDir: 'build',
        rollupOptions: {
            input: {
                admin: 'src/admin/index.js',
                frontend: 'src/frontend/index.js',
            },
            output: {
                entryFileNames: '[name].js',
                chunkFileName
Read more
@mralaminahamed
Ships withwp-dev-skills

Covers the complete WordPress plugin development lifecycle — build, test, audit, release, and ship to WP.org — for Claude Code, Gemini CLI, Cursor, Windsurf, Cline, Codex, GitHub Copilot, opencode, and more.

Stars on GitHub

Momentum

stars in total
28
Star history of mralaminahamed/wp-dev-skills on GitHub, a chart by star-history.com

Other skills on wp-dev-skills.

wp-ci-qa

wp-ci-qa

Use when a pull request has QA failures, a \"Testing Failed\" label, or QA comments reporting broken features — reading QA…

wp-database

wp-database

Use when a WordPress plugin needs a custom database table — creating with dbDelta (strict SQL format: two spaces before PRIMARY…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about wp-build-tools.

Which coding agents can use wp-build-tools?
wp-build-tools installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.