Blockstudio
Back to Blog

Written by

Dennis

At

Sat Feb 07 2026

Introducing Blockstudio 7

A complete rewrite of the WordPress block framework. Now free and open source, with file-based pages, an HTML-to-block parser, and an architecture built for AI coding agents.

Blockstudio 7 is here. This is the biggest release in the history of the project: a complete, ground-up rewrite of the entire codebase. Every class, every hook, every line of code has been rebuilt from scratch with a focus on modern PHP, WordPress coding standards, and long-term maintainability.

But this isn't just a refactor. Blockstudio 7 introduces major new features like file-based pages and patterns, a post meta storage system, SEO integration, and a brand new HTML-to-block parser that powers it all. On top of that, Blockstudio is now completely free and open source.

Let's dive into everything that's new.

Free and open source

I've been working on Blockstudio since 2020, shipping dozens of releases over the years. The people who used it loved it, but finding market fit for a commercial WordPress block framework was always a challenge.

What changed the equation is LLMs. AI coding assistants are now good enough to write block code, but they need clean, file-based structures to work with. WordPress block markup is messy: serialized HTML comments with embedded JSON attributes, mixed with DOM structure. That's hard for humans and even harder for LLMs to get right.

Blockstudio's file-first approach was always designed to keep things simple: a block.json and a PHP template in a folder. No database entries, no React, no build step. With v7, that philosophy goes even further. The HTML-to-block parser lets you write plain HTML and have it converted into valid block markup automatically. Everything stays in the filesystem. The only database writes are automatic page syncs, and even those are driven by file templates.

Making Blockstudio open source is the natural next step. The more LLMs train on Blockstudio code, the better they get at generating it. An open codebase, open documentation, and a pre-built AI context file that any tool can consume: that's how you build the best environment for AI-assisted WordPress development.

The full plugin is available on GitHub for anyone to use, fork, and contribute to. No license keys, no paywalls, no feature gates.

New features

File-based pages

This is one of the biggest additions in 7.0. You can now define entire WordPress pages as file templates that automatically sync to the database as native block content.

Create a folder with a page.json and a template file:

page.json
{
  "name": "about",
  "title": "About Us",
  "slug": "about",
  "postStatus": "publish"
}
index.php
<div class="about-page">
  <h1>About Us</h1>
  <p>Welcome to our site.</p>
</div>

Blockstudio parses the HTML into WordPress blocks, creates the page in the database, and keeps it in sync whenever the template file changes.

Keyed block merging

When templates sync, user edits would normally be overwritten. The key attribute solves this by preserving user content across syncs:

index.php
<h1 key="hero-title">Default Title</h1>
<p key="hero-description">Default description.</p>

Blocks with matching keys keep their user-edited content when the template updates. Blocks without keys are replaced entirely.

Block bindings

As an alternative to keys, you can use WordPress core's Block Bindings API to connect blocks directly to post meta. This is not a Blockstudio feature, it is a native WordPress API. Blockstudio simply passes the metadata attribute through to the generated block markup. Content lives in meta instead of block markup, so template syncs never destroy user edits. The data is also queryable via WP_Query and available through the REST API.

index.php
<h1 metadata='{"bindings":{"content":{"source":"core/post-meta","args":{"key":"hero_title"}}}}'>
  Default Title
</h1>

Both approaches can be used in the same template.

Editing controls

Pages support blockEditingMode and templateLock to control what users can modify:

page.json
{
  "name": "landing",
  "title": "Landing Page",
  "blockEditingMode": "contentOnly",
  "templateLock": "all"
}

This locks the page structure while still allowing users to edit text and media. Individual elements can override the page-level setting with a blockEditingMode attribute in the template.

Pinning to post IDs

Use postId to bind a page template to an existing WordPress post, preventing duplicate pages and ensuring the template always updates the correct post:

page.json
{
  "name": "home",
  "title": "Home",
  "postId": 2
}

For full details, see the Pages documentation.

File-based patterns

Similar to pages, you can now define block patterns as file templates. Write your pattern in HTML, and Blockstudio parses it into block markup and registers it as a native WordPress block pattern. They appear in the block inserter and can be placed anywhere by users.

pattern.json
{
  "name": "hero-section",
  "title": "Hero Section",
  "categories": ["featured"],
  "keywords": ["hero", "banner"]
}
index.php
<div class="hero">
  <h1>Welcome</h1>
  <p>Get started today.</p>
</div>

Unlike pages, patterns don't create database entries. They're registered in memory on every page load. See the Patterns documentation.

HTML-to-block parser

Both pages and patterns are powered by a new HTML parser that converts standard HTML templates into WordPress block markup. It handles container blocks (like groups and columns) and leaf blocks (like paragraphs and headings) automatically. The parser uses a trait-based renderer architecture, making it easy to extend with support for additional block types via the blockstudio/parser/renderers filter:

functions.php
add_filter( 'blockstudio/parser/renderers', function ( $renderers, $parser ) {
    $renderers['acme/hero'] = function ( $element, $attrs, $parser ) {
        $content = $parser->get_inner_html( $element );
        $html    = '<div class="acme-hero">' . $content . '</div>';

        return array(
            'blockName'    => 'acme/hero',
            'attrs'        => $attrs,
            'innerBlocks'  => array(),
            'innerHTML'    => $html,
            'innerContent' => array( $html ),
        );
    };

    return $renderers;
}, 10, 2 );

Once registered, you can use the block in any page or pattern template:

index.php
<block name="acme/hero" background="/hero.jpg">
  <h1>Welcome to our site</h1>
</block>

Storage

Fields can now store their values in post meta or site options, in addition to block attributes. This is a big one:

block.json
{
  "id": "subtitle",
  "type": "text",
  "label": "Subtitle",
  "storage": {
    "type": "postMeta"
  }
}

With values in post meta, you can:

  • Query posts by field values using WP_Query and meta_query
  • Access field data through the REST API for headless setups
  • Share data with other plugins like SEO tools and caching layers

You can also store values in the options table for global, site-wide settings:

block.json
{
  "id": "phone",
  "type": "text",
  "label": "Phone Number",
  "storage": {
    "type": "option",
    "optionKey": "company_phone"
  }
}

See the Storage documentation for the full API.

Custom fields

Reusable field definitions can now be shared across multiple blocks. Define a set of fields once, then reference them from any block. This eliminates repetition when multiple blocks share the same field structure.

Create a field.json in your blockstudio directory:

fields/hero/field.json
{
  "name": "hero",
  "title": "Hero Section",
  "attributes": [
    { "id": "heading", "type": "text", "label": "Heading", "default": "Hello World" },
    { "id": "description", "type": "textarea", "label": "Description" }
  ]
}

Then reference it from any block using the custom/ prefix:

block.json
{
  "blockstudio": {
    "attributes": [
      { "type": "custom/hero", "idStructure": "hero_{id}" }
    ]
  }
}

The idStructure property prefixes each field ID, so heading becomes hero_heading. You can also override individual field properties per-instance with the overrides key.

See the Custom Fields documentation.

Tailwind CSS v4

Tailwind support has been completely rebuilt for v4. Instead of compiling client-side via the CDN and saving to disk on post save (the v6 approach), Blockstudio 7 compiles Tailwind server-side on every frontend request via TailwindPHP. No Node.js, no CLI, no build step required.

The compilation uses candidate-based caching: Blockstudio extracts all CSS class names from the final HTML, sorts and hashes them together with your CSS config, and checks for a cached file. Same classes produce the same cache hit, even when the surrounding HTML changes (nonces, timestamps, dynamic content).

Configuration uses Tailwind v4's CSS-first syntax. Define custom themes and utility classes directly in your blockstudio.json or via the blockstudio/tailwind/css filter:

functions.php
add_filter('blockstudio/tailwind/css', function ($css) {
  return $css . '
    @theme {
      --color-brand: #4f46e5;
    }

    @layer utilities {
      .container-narrow {
        max-width: 48rem;
        margin-inline: auto;
      }
    }
  ';
});

In the block editor, a bundled Tailwind CDN script provides live preview as you type. The classes field type offers autocomplete for all Tailwind utilities. The frontend always uses the server-compiled CSS, injected as an inline style tag before </head>.

See the Tailwind documentation for the full setup.

Interactivity API

Blockstudio now supports the WordPress Interactivity API. Enable it in your block.json:

block.json
{
  "blockstudio": {
    "interactivity": true
  }
}

Add data-wp-* directives to your template:

index.php
<div useBlockProps
     data-wp-interactive="myBlock"
     data-wp-context='{ "isOpen": false }'>
  <button data-wp-on--click="actions.toggle"
          data-wp-bind--aria-expanded="context.isOpen">
    Toggle
  </button>
  <div data-wp-bind--hidden="!context.isOpen">
    This content is toggled by the button.
  </div>
</div>

And create a script.js with your store logic:

script.js
import { store, getContext } from '@wordpress/interactivity';

store('myBlock', {
  actions: {
    toggle: () => {
      const context = getContext();
      context.isOpen = !context.isOpen;
    },
  },
});

Blockstudio handles the importmap, module loading, and directive processing in both the frontend and the block editor. Blocks that only use declarative directives with data-wp-context (like data-wp-bind--hidden or data-wp-text) work without any JavaScript at all. Server-side state via wp_interactivity_state() is also supported on the frontend.

See the Interactivity documentation for the full setup.

SEO content analysis

Blockstudio blocks are dynamic, so their field content is invisible to SEO plugins by default. Blockstudio 7 fixes this with automatic integrations for Yoast SEO, Rank Math, and SEOPress. Text values from text, textarea, richtext, wysiwyg, and link fields (including nested repeater rows) are extracted and fed into each plugin's content analysis. SEO plugins can now properly analyze your block content for keyword density, readability, and other metrics. No configuration needed.

Repeater default rows

Repeater fields now support a default property with an array of pre-filled rows. When a block is inserted, the repeater is populated with the specified rows and their values, both in the editor and on the frontend:

block.json
{
  "id": "features",
  "type": "repeater",
  "label": "Features",
  "default": [
    { "title": "Fast", "icon": "bolt" },
    { "title": "Secure", "icon": "shield" }
  ],
  "attributes": [
    { "id": "title", "type": "text", "label": "Title" },
    { "id": "icon", "type": "text", "label": "Icon" }
  ]
}

The min property also works with field-level defaults: if a repeater has min: 3 and its inner fields have default values, the auto-generated rows are pre-filled with those defaults instead of being empty.

Enhancements and fixes

  • Repeater min with field defaults: auto-generated min rows now use field-level default values on both frontend and editor
  • Tailwind editor styles: compiled Tailwind CSS is now injected into the block editor iframe alongside the CDN, so custom @apply rules and theme config work in the editor
  • AI context file: the blockstudio-llm.txt has been rebuilt as a static file assembled from the full v7 documentation and deduplicated JSON schemas (~48k tokens), replacing the dynamic generation from v6
  • Code field popout: the code field can now be opened in a separate window, with independent undo/redo and JavaScript syntax highlighting
  • Tailwind v4 server-side compilation: see the Tailwind section above
  • API version 3: blocks now render correctly in the iframed editor, including the site editor and responsive previews
  • Dot notation for assets: cleaner file naming convention for asset suffixes (*.inline.css, *.editor.js, *.scoped.css)
  • Fixed bs_render_block() warning from WP_Block_Supports when using useBlockProps
  • Fixed conditional fields not respecting default values on first load
  • Fixed dollar signs being stripped from <RichText /> content on the frontend
  • Fixed populate feature to work with taxonomies registered by other plugins
  • Fixed optionsPopulate null error in WPML contexts

Under the hood

Complete rewrite

This isn't a refactor or a cleanup. Every class has been rewritten from scratch. The result is a cleaner, more modular codebase that's easier to maintain and extend.

Modern PHP

Blockstudio 7 requires PHP 8.2+ and uses modern type declarations throughout.

Breaking changes

As a major version update, 7.0 includes several breaking changes. Most have backward-compatible fallbacks, but you should review them before upgrading. For a complete migration guide, see the v7 migration docs.

Hook names now use snake_case

All PHP hooks have been renamed from camelCase to snake_case, matching WordPress core conventions:

functions.php
// Before (v6)
add_filter('blockstudio/settings/blockEditor/cssClasses', function() {
    return ['my-stylesheet'];
});

// After (v7)
add_filter('blockstudio/settings/block_editor/css_classes', function() {
    return ['my-stylesheet'];
});

The old camelCase names still work, but we recommend updating.

Field switch defaults to off

The switch property now defaults to false instead of true. In v6, every field had an invisible toggle on the left edge that was enabled by default. In v7, switch is opt-in and uses a visible eye icon in the field label. If you relied on the default switch behavior, add "switch": true to your field definitions.

Asset file naming uses dot notation

Asset suffixes now use dots instead of dashes (style.inline.css instead of style-inline.css). The old dash notation still works, but dot notation is the recommended convention going forward.

npm import prefix

ES module imports now use npm: instead of blockstudio/:

script.js
// Before (v6)
import confetti from "blockstudio/canvas-confetti@1.6.0";

// After (v7)
import confetti from "npm:canvas-confetti@1.6.0";

The blockstudio/ prefix is still supported for backward compatibility.

Removed features

Admin area and code editor. The WordPress admin settings page and the built-in block code editor have both been removed. All configuration now happens through blockstudio.json and PHP filters, which means your setup lives in version control alongside your blocks.

The code editor was useful in earlier versions for previewing blocks, but it never reached full parity with a real development environment. Several plugin features were held back over the years because they couldn't be supported inside the standalone editor. It was also never going to be a replacement for a full IDE. Removing it allows the plugin to focus entirely on file-based development without compromise.

License key. No longer needed. Blockstudio is free and open source.

Block library. The built-in "Blockstudio Elements" library (Gallery, Slider, Image Comparison, Code, Icon) has been removed. These were pre-built example blocks that shipped with the plugin. If you were using them, copy the block folders from v6 into your theme's blockstudio directory.

Getting started

Install Blockstudio 7 and create your first block in minutes. Check out the Getting Started guide for a step-by-step walkthrough, or the v7 migration guide if you're upgrading from v6.

The full source is on GitHub. Issues, PRs, and feedback are welcome.

On this page