How to Use @wordpress/scripts when Creating a Gutenberg Block
Let’s begin with the understanding that you can not use regular JavaScript when creating blocks for Gutenberg. Well, you could try that but the code will be hardly readable. Believe me, I know what I’m talking about because I started learning blocks in 2019 with regular JavaScript without using what I am going to show you in this tutorial.
In this lesson we are about to create a project for our custom Gutenberg block and configure the development environment using @wordpress/scripts
tool. This tool is what I use personally when I create any blocks either for my plugins or for my client projects.
What is JSX and Why We Need It So Bad?
In order to answer to the “Why” question let’s just take a look at this example from one of my very first tutorials about Gutenberg blocks (I decided to not update that tutorial for a reason).
So, there you can find a regular JavaScript implementation like this:
return (
wp.element.createElement( wp.element.Fragment, {},
wp.element.createElement( wp.editor.InspectorControls, {},
wp.element.createElement( wp.editor.PanelColorSettings,
{
title: 'Awesome Color Options',
colorSettings: [
{
colors: colorSamples,
value: props.formColor.color,
label: 'Form Color',
onChange: props.setFormColor,
}
]
},
),
),
wp.element.createElement( 'div', { className: formClasses },
wp.element.createElement( 'div', { className: 'misha-form-wrap' },
wp.element.createElement( 'div', {},
'Enter your email...'
),
wp.element.createElement( 'div', { style: buttonStyles },
'Subscribe'
)
)
)
)
);
Of course in the tutorial I have it simplified a bit by assigning some constants like const el = wp.element.createElement()
or const Fragment = wp.element.Fragment
.
And now check how the same piece of code looks when written with JSX:
return (
<Fragment>
<InspectorControls>
<PanelColorSettings
title="Awesome Color Options"
colorSettings={[
{
colors: colorSamples,
value: props.formColor.color,
label: 'Form Color',
onChange: props.setFormColor,
}
]}
/>
</InspectorControls>
<div className={ formClasses }>
<div className="misha-form-wrap">
<div>Enter your email...</div>
<div style={ buttonStyles }>Subscribe</div>
</div>
</div>
</Fragment>
)
Don’t you think that the second piece of code looks simple and kind of familiar?
Transform everything to JSX
Writing JavaScript code in JSX is like writing HTML. It is used not only by Gutenberg block developers but by any React developers.
It allows to transform this code presence:
wp.element.createElement( MyElement, props, children... )
To this:
<MyElement prop={}>children</MyElement>
So every React (or Gutenberg) component now looks like HTML tag. And when you need some HTML tags inside your block then you just write HTML almost without changes.
Using imports
Sometimes when creating a block, you will need some Gutenberg components for it. It could be <InspectorControls>
if you are about to create a panel with block settings or maybe just registerBlockType()
function which is required for any block by the way.
Just start your JavaScript file with some import
tags in order to make the components you need to become available inside the file.
import { Fragment } from "@wordpress/element";
import {
InspectorControls,
PanelColorSettings
} from '@wordpress/block-editor';
Think of it like an analogy to include()
function in PHP.
How to Start Using JSX?
Okay, we’ve decided, JSX is great, but what are the pitfalls? There is the only one – browsers do not understand JSX. So usually we have two JavaScript files – one is for developers and another one is for browsers and we use either Webpack or Gulp to automatically generate the file for browsers (and also minify it along the way or do some other stuff if needed).
It may look like this:

src/index.js
file but when all is done or we just need to preview the result, we run some Webpack commands and build/index.js
is being generated.Configuring Webpack could be not the easiest thing to do but we don’t need it, because @wordpress/scripts
does everything for us.
I also believe that struggling with this step is what stops other developers from creating blocks the correct way, so they become afraid of NodeJS, React and JavaScript and stick to creating Gutenberg blocks with PHP using some plugins like ACF which should never ever be used for that purpose!
Installing @wordpress/scripts
The good news here is that we only need one NPM module to install.
npm install @wordpress/scripts --save-dev
But before that check that your Node JS version is higher than 14.0
by running a command node --version
and also that NPM version is 6.14.4
or above by running npm --version
.
Difference between “wp-scripts start” and “wp-scripts build”
Once installation is done we have a bunch of scripts to use, but for the block creation we really need only two of them:
wp-scripts start
– it watches for the changes insrc/index.js
file (more about file structure below) and every time you smash “Save” orCmd + S
it compiles the browser-ready code of the block in development mode. In order to exit the watching mode, pressCtrl + C
(on Mac OS).wp-scripts build
– it compiles the block code for production mode and minifies the result JavaScript. Run it when you finish the development work.
In order to have the possibility to run these scripts in the command line we need to add them into the package.json
file which is a part of your project now.
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start"
}
Once done, we can run the scripts using NPM command npm run <script name>
.
Understanding the file structure
A little bit above I showed you an example of file structure:

src/index.js
– is a fallback entry point used by@wordpress/scripts
build/index.js
– the default output file.
So you can just create these two files and it is going to be pretty much it.
But it also supports some custom script names, but in this case you have to locate your block.json
file in the src
folder and then set one of the parameters – editorScript
, script
or viewScript
. Example:
{
"editorScript" : "file:editor.js"
}
And this is the file structure:

src
folder ourselves, files in the build
folder will be generated by the tool.This approach could be helpful when you have multiple blocks within a single WordPress plugin (or theme), but it is not the only way. We are going to talk about it in a separate lesson.

Misha Rudrastyh
Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.
Need some developer help? Contact me