create-acf-block CLI

A command line tool for stubbing out new blocks with Advanced Custom Fields

 * Block Name: Hero
 * Description: Displays a full width hero image with text overlay

// $data is what we're going to expose to our render template
$data = array(
    'example_field' => get_field( 'example_field' ),
    'another_field' => get_field( 'another_field' )

// Dynamic block ID
$block_id = 'hero-' . $block['id'];

// Check if a custom ID is set in the block editor
if( !empty($block['anchor']) ) {
    $block_id = $block['anchor'];

// Block classes
$class_name = 'hero-block';
if( !empty($block['class_name']) ) {
    $class_name .= ' ' . $block['className'];

 * Pass the block data into the template part
        'block'      => $block,
        'is_preview' => $is_preview,
        'post_id'    => $post_id,

        'data'       => $data,
        'class_name' => $class_name,
        'block_id'   => $block_id,

    "name": "hero",
    "title": "Hero",
    "description": "Displays a full width hero image with text overlay",
    "category": "theme",
    "apiVersion": 2,
    "acf": {
        "mode": "preview",
        "renderTemplate": "theme/blocks/hero/block.php"
    "supports": {
        "anchor": true,
        "jsx": true

 * Block Name: Hero
 * Description: Displays a full width hero image with text overlay

// The block attributes
$block = $args['block'];

// The block data
$data = $args['data'];

// The block ID
$block_id = $args['block_id'];

// The block class names
$class_name = $args['class_name'];

$template = array(
    array('core/heading', array(
        'level' => 2,
        'content' => 'This is a default heading',
    array( 'core/paragraph', array(
        'content' => 'This is placeholder paragraph text.',
    ) )

$allowed_blocks = array( 'core/heading', 'core/paragraph', 'core/image' );

<div id="<?php echo $block_id; ?>" class="<?php echo $className; ?>">
        template="<?php echo esc_attr( wp_json_encode( $template ) ); ?>"
        allowedBlocks="<?php echo esc_attr( wp_json_encode( $allowed_blocks ) ); ?>"/>

function create_acf_block_cli_register_blocks() {
    // ACF Block Registration
    foreach ($blocks as $block) {
        register_block_type( get_template_directory() . '/blocks/' . $block );
add_action( 'init', 'create_acf_block_cli_register_blocks' );

1. Download the package

The create-acf-block CLI is a composer package.

composer global require joeyfarruggio/create-acf-block

2. Ensure Global Composer Binaries are in Your PATH

If it’s your first time installing a global Composer package, ensure that the global Composer binaries directory is in your system’s PATH. This will allow you to run the create-acf-block command globally.

To find out the path to your global composer binaries:

composer global config bin-dir --absolute

The command above will output a path. You need to add this path to your system’s PATH. Below are instructions based on your operating system:

macOS and Linux

For most folks, your global composer binaries are in ~/.composer/vendor/bin. If that’s the case for you, add it to your .bashrc, .bash_profile, or .zshrc file:

export PATH=~/.composer/vendor/bin:$PATH


(Disclaimer: I don’t use Windows, so I had GPT write this section)

  1. Right-click on the Computer icon and choose Properties.
  2. Click on the Advanced system settings link.
  3. Click on the Environment Variables button.
  4. In the System Variables section, find the PATH variable, select it, and click Edit.
  5. In the Edit Environment Variable window, add a semicolon to the end of the value and then append the path to your global composer binaries.
  6. Click OK to save your changes.

3. Using the CLI

After installation, you can utilize the CLI tool globally:


Follow the on-screen prompts to create your ACF block.

The first tme you run the command you will be see a series of config prompts. If you ever need to reset these you can run create-acf-block set-config.

modernWPdev Slack

Join over 130 other devs for free

    Joey Farruggio

    I'm Joey 👋,

    I've been building with WordPress for almost 10 years. I create tools for developers serve clients as an contract web developer.