WordPress plugin for scaffolding native Gutenberg blocks in block themes with per-block builds.
- Per-block builds with @wordpress/scripts
- React-based blocks with JSX
- Standard block structure (src/ → build/)
- Designed for block themes (FSE)
- Moiraine theme templates included
- Simple WP-CLI commands
- WordPress 6.0+
- PHP 8.0+
- WP-CLI
- Node.js & npm (for building blocks)
This is a development tool for scaffolding blocks, so install it as a dev dependency:
composer require imagewize/wp-native-blocks --devNote: The --dev flag is recommended because this plugin is only used during block development, not in production. The version constraint (:^3.0) is required.
- Download and install the plugin
- Activate in WordPress admin
- Use via WP-CLI
wp block create vendor/block-nameThis creates a complete block structure:
blocks/block-name/
├── package.json # @wordpress/scripts setup
├── .gitignore
└── src/ # Source files
├── block.json # Block metadata
├── index.js # Registration
├── edit.jsx # Editor component (React)
├── save.jsx # Frontend component (React)
├── style.scss # Frontend styles
├── editor.scss # Editor styles
└── view.js # Optional frontend JS
# Use Moiraine hero template
wp block create imagewize/hero --template=moiraine-hero
# Use generic innerblocks template
wp block create imagewize/container --template=innerblocks# Create in custom directory (default: blocks)
wp block create imagewize/custom --blocks-dir=custom-blocksThe plugin supports creating blocks for specific sites in a multisite installation. Use the --url parameter to target a specific site and its active theme (including child themes):
# Create block for main site
wp block create imagewize/hero --url=https://example.com --path=web/wp
# Create block for subsite (targets the subsite's active theme)
wp block create imagewize/stats --url=https://example.com/blog/ --path=web/wp
# Create block for child theme on subsite
wp block create imagewize/custom --url=https://example.com/shop/ --path=web/wpImportant: The plugin must be network-activated for multisite usage:
wp plugin activate wp-native-blocks --network --path=web/wpHow it works:
- Uses
get_stylesheet_directory()to support both parent and child themes - Respects the
--urlparameter to target specific sites in multisite - Automatically creates blocks in the active theme of the specified site
- Updates the correct theme's
functions.phpfile
For Bedrock-based projects with Trellis VM:
# From host machine (recommended)
trellis vm shell --workdir /srv/www/example.com/current -- wp block create imagewize/hero --path=web/wp
# From inside VM shell
trellis vm shell
cd /srv/www/example.com/current
wp block create imagewize/hero --path=web/wp
# For multisite in Trellis VM
trellis vm shell --workdir /srv/www/example.com/current -- wp block create imagewize/stats --url=http://example.test/blog/ --path=web/wpWhy --path=web/wp is needed:
- WP-CLI needs to locate WordPress core to load plugins
- Without
--path, WP-CLI can't find the plugin or WordPress installation - The
web/wpdirectory contains WordPress core in Bedrock structure
After creating a block:
cd blocks/your-block
npm install
npm run start # Development with hot reload
npm run build # Production buildThe build outputs to build/ directory:
build/
├── block.json
├── index.js
├── index.css # Editor styles
└── style-index.css # Frontend styles
base- Minimal starter with RichText example
innerblocks- Container with InnerBlocks support
moiraine-hero- Hero section with background image
More templates coming soon!
The plugin automatically adds this code to your theme's functions.php:
add_action('init', function () {
$blocks_dir = get_stylesheet_directory() . '/blocks';
if (!is_dir($blocks_dir)) {
return;
}
$block_folders = scandir($blocks_dir);
foreach ($block_folders as $folder) {
if ($folder === '.' || $folder === '..') {
continue;
}
$block_json_path = $blocks_dir . '/' . $folder . '/build/block.json';
if (file_exists($block_json_path)) {
register_block_type($block_json_path);
}
}
}, 10);Note: The code uses get_stylesheet_directory() instead of get_template_directory() to support child themes. This ensures blocks are loaded from the active theme (child or parent).
Create custom templates in your theme:
your-theme/block-templates/
└── my-template/
├── package.json.stub
├── .gitignore.stub
└── src/
├── block.json.stub
├── index.js.stub
├── edit.jsx.stub
├── save.jsx.stub
├── style.scss.stub
├── editor.scss.stub
└── view.js.stub
Use placeholders in your stubs:
{{BLOCK_NAME}}- Full block name (e.g.,vendor/block-name){{BLOCK_SLUG}}- Slug version (e.g.,vendor-block-name)
- Create block:
wp block create vendor/name --template=moiraine-hero - Install dependencies:
cd blocks/name && npm install - Start development:
npm run start - Edit in WordPress: Block appears in editor automatically
- Build for production:
npm run build
This plugin is specifically designed for modern block themes (FSE) because:
- Standardized block location (
blocks/) - Per-block builds (simple, independent)
- React-based architecture
- Clean, predictable structure
- Focused on modern WordPress
Each block follows this consistent pattern:
your-block/
├── package.json # Dependencies and scripts
├── .gitignore # Ignores node_modules/ and build/
├── src/ # Your source code
│ ├── block.json # Block configuration
│ ├── index.js # Main entry point
│ ├── edit.jsx # Editor component
│ ├── save.jsx # Save component
│ ├── style.scss # Frontend styles
│ ├── editor.scss # Editor-only styles
│ └── view.js # Optional interactivity
└── build/ # Compiled output (gitignored)
├── block.json # Copied from src/
├── index.js # Compiled JavaScript
├── index.css # Compiled editor styles
└── style-index.css # Compiled frontend styles
MIT
Built by Imagewize
Icon: IconPark Block One from Blade UI Kit
Version 3.0.0+ - This package evolved from imagewize/sage-native-block which was designed for Sage/Acorn themes. Version 3.0.0 represents a complete rewrite focused on standard WordPress block themes (FSE). See CHANGELOG.md for full migration details.