Vite Plugin: Gutenberg Blocks

Gutenberg block development is still something of a work-in-progress for WordPress. Until recently, it required some major workarounds to develop more than one block to the plugin (we’re told it’s better now) and the tech-stack powering the whole enterprise is pretty ancient. In short, it feels like a strange no-man’s-land between a proper development experience and cycling with stabilisers on.

We thought we’d give a Vite-powered development process a go with Gutenberg, and while there are a few limitations (no Hot Module Reloading), it’s still a superior experience. For good measure, we even made a create-block script that makes adding new Gutenberg blocks to your plugin a breeze. Add in automatic block loading, and we’re quite happy with what we’ve got here.


While something of a hybrid package (since it creates a PHP-based plugin in WordPress), we gave this one to NPM because it’s mostly JavaScript-powered. There’s a small amount of setup involved so let’s get to the numbers:

  1. Create a new folder in your wp-content/plugins folder to house your new block library
  2. Initiate a new JavaScript package by running npm init -y inside your new plugin folder
  3. Install this package inside your new plugin folder (i.e. npm install -D vite-plugin-gutenberg-blocks
  4. Run npx -p vite-plugin-gutenberg-blocks init in your plugin folder to create a development folder and a register-blocks.php file
  5. cd development
  6. npm install to install the required node dependencies
  7. Now you can run npm run create to start off the block creation script. Answer the questions and a new block will be created in your development folder. You can add as many blocks as you like and they will be automatically loaded by WordPress once you…
  8. require_once 'register-blocks.php'; in your plugins entry PHP file.

From the development folder you can now npm run dev and npm run prod to develop your Gutenberg blocks library with Vite.


  • Automatic configuration of Vite
  • Copies and creates required assets
  • Externalised PostCSS stylesheet processing
  • Supports PostCSS, SCSS and CSS stylesheets (.css or .scss)
  • Watch mode for developing your block library
  • Support for PHP-rendered blocks

Speaking of the last one there…

Dynamic Blocks (PHP-rendered)

Your average Gutenberg block is really just a fancy React mini-app that allows users to save HTML output into their post via the editor. When the output is delivered to the frontend, it’s generally just static HTML with some settings from Gutenberg’s editor. This works fine for elements like buttons, forms, galleries et al., but it’s not so good for things that require dynamic content, like posts or other pieces of live data.

This is where Gutenberg’s dynamic blocks come in. Essentially, you let JavaScript handle the backend editor stuff and then handover the actual rendering to good old PHP.

We won’t go through the actual process of setting this up beyond what’s related to this package:

In your blocks block.json file, add either "render": "file:./template.php" or "render": "file:./render.php" to the JSON (the plugin will only look for one of these two filenames).

Create the PHP file in your block’s development folder. It will be automatically copied to your block’s build folder along with the other build files.

Create Block Stubs

Stubs are template files that are used when creating a new block from within your development environment. By default, the create script will use stub files from inside the package. However, if you wish to override these with your own stub files, you can do so by placing one or more of them inside your development folder at the locations shown below:

/ development
/ packages
/ stubs
/ src

You can choose to publish these stub files to your development folder during the init script, or at a later time by running:

npx -p vite-plugin-gutenberg-blocks publish


As previously mentioned, this plugin doesn’t currently support Vite’s HMR (Hot Module Reloading) mode, so you’ll have to manually reload the page whenever you make a change to your code. Wait until watch mode has finished rebuilding the block in response to your changes though.

Watchers run independently on each block, so once you start watch mode, a change to one block will only rebuild that one block, giving you a very quick development process.

Migration to Version 2.x

Version 2 of vite-plugin-gutenberg-blocks introduces support for Vite 5 and requires some changes to any existing packages in your project.

Upgrade NodeJS version

Vite 5 drops support for Node versions 14.x, 16.x, 17.x and 19.x. Therefore make sure you’re running either version 18.x, 20.x or 21.x on your operating system.

Change package.json to a module

Vite 5 drops support for CommonJS (or require) syntax. Therefore, all Vite projects must be marked as module-type projects. To change this, in each of your blocks, edit the package.json file and add the following:

"type": "module"

Change PostCSS config file to new ES6 modules format

Changing to a module-type project means that, by default, ES6 exports are now expected from all .js files inside your project/block. Therefore we need to tweak any PostCSS config files that were written in the old CommonJS module.exports format to the following:

export default {
plugins: {
"postcss-nested": {},
"postcss-import": {},
autoprefixer: {},

Relocated CreateBlock script (v2.1.0+)

Previously, the “create” script for bootstrapping new blocks in your environment was copied to your development folder during the “init” script. This worked well, but made it impossible to make changes to the script for existing development environments. Therefore, we made the decision to move it inside the vite-plugin-gutenberg-blocks package.

To change to using the new create script, inside your package.json file in your existing development folder and find the following line:

"scripts": {
"create": "node ./scripts/create.mjs"

and change it to:

"scripts": {
"create": "npx -p vite-plugin-gutenberg-blocks create"

Using default stubs with optional overrides

Rather than publishing the createBlock template stubs during your init function and relying on those, the default is now to use stubs defined inside the package unless there is an override file inside your development environment folder.

You will now be asked during the init script whether or not you wish to publish the stubs.

If you change your mind later, you can use npx -p vite-plugin-gutenberg-blocks publish to publish the stubs to your development environment.

For full instructions, see the section on “stubs” above.

What do you think?

Any thoughts/suggestions about this package can be posted on our GitHub repo.

Part of evoMark's contribution to Free and Open Source Software (FOSS)

To read more about evoMark and our open-source software, head to our Open-Source Software page

npm i vite-plugin-gutenberg-blocks