The conversation usually starts with a demo. A developer opens Divi, Bricks, Breakdance, or Etch WP and produces a polished layout in a few minutes. Then the question is posed: “Can you do that with just a block theme?” The implied answer is no.
The working assumption, repeated often enough that it has acquired the texture of received wisdom, is that Full Site Editing and core blocks produce functional but aesthetically limited results, and that third-party builders are required for anything a real client would pay for.
That assumption is wrong. It is also not innocent — and both of those claims deserve to be examined with some care.
The Financial Arrangement Nobody Discloses
Before the technical argument, there is a structural one. Third-party page builders generate recurring revenue for the developers who recommend them.
Divi licenses are sold at $329,000 COP per year (US $89) or $922,000 COP as a one-time fee (US $249) for unlimited sites. Bricks Builder charges $922,000 COP per year (US $249) for an unlimited-site annual license, or a one-time lifetime fee of $2,217,000 COP (US $599). Breakdance charges $370,000 COP per year (US $99.99) for a single-site license, or $740,000 COP per year (US $199.99) for unlimited sites, with an agency tier reaching $2,960,000 COP per year (US $799.99).
The newer generation of developer-focused tools carries higher entry costs: Etch WP, a visual development environment built by Digital Gravy, prices its annual plans at $366,000 COP (US $99) for a Freelancer license covering three production sites, $737,000 COP (US $199) for an Agency license covering 25 sites, and $1,107,000 COP (US $299) for an Agency Elite license covering 75 sites.
Every time a developer recommends one of these tools to a client and the client purchases a license, the developer may receive an affiliate commission. None of that is disclosed in the articles and tutorials that compare these tools favorably against the native block editor. The comparison is framed as a technical judgment. The financial incentive is invisible.
Core blocks carry no license. A block theme built entirely on core functionality carries no recurring tool cost; where a premium theme requires a license for its extended feature set, that cost is typically lower than a comparable builder license — and lower still once the builder’s paid add-ons are factored in.
The developer who recommends a professionally built block theme rarely earns a commission from that recommendation — some premium themes do run affiliate programs, but the ecosystem is a fraction of the size and reach of the builder affiliate market — and in the case of a theme built entirely on core WordPress functionality, there is nothing to commission at all.
That asymmetry does not mean every builder recommendation is corrupt. It does mean that the professional case for builders deserves more scrutiny than it typically receives, and that the claim “core blocks cannot compete” should be tested against the actual capabilities of the platform rather than accepted on the authority of people with a financial interest in the answer.
What a Design System Looks Like in theme.json
The first capability builders advertise is a global design system: a centralized interface for controlling typography, color, and spacing across the entire site. Divi has its Design Settings. Bricks has its Global Colors and Global Fonts panels. Etch WP surfaces its design tokens through a visual interface that writes CSS custom properties in real time.
theme.json version 3, supported from WordPress 6.6 onward, is a declarative design system that covers the same ground without a builder. The following configuration defines a constrained, locked palette, a named typographic scale, and a spacing token set — all of which the block editor respects natively across every core block:
{
"$schema": "https://schemas.wp.org/wp/6.8/theme.json",
"version": 3,
"settings": {
"color": {
"custom": false,
"defaultPalette": false,
"palette": [
{ "slug": "primary", "color": "#1a1a2e", "name": "Primary" },
{ "slug": "accent", "color": "#e94560", "name": "Accent" },
{ "slug": "surface", "color": "#f5f5f5", "name": "Surface" },
{ "slug": "base", "color": "#ffffff", "name": "Base" }
]
},
"typography": {
"customFontSize": false,
"fontSizes": [
{ "slug": "sm", "size": "0.875rem", "name": "Small" },
{ "slug": "base", "size": "1rem", "name": "Base" },
{ "slug": "lg", "size": "1.25rem", "name": "Large" },
{ "slug": "xl", "size": "1.75rem", "name": "XL" },
{ "slug": "2xl", "size": "2.5rem", "name": "2XL" },
{ "slug": "3xl", "size": "3.5rem", "name": "3XL" }
]
},
"spacing": {
"spacingSizes": [
{ "slug": "xs", "size": "0.5rem", "name": "XS" },
{ "slug": "sm", "size": "1rem", "name": "SM" },
{ "slug": "md", "size": "2rem", "name": "MD" },
{ "slug": "lg", "size": "4rem", "name": "LG" },
{ "slug": "xl", "size": "8rem", "name": "XL" }
]
}
}
}
custom: false and customFontSize: false are not stylistic choices. They enforce the design system at the editor level: a client opening the site editor cannot introduce an off-palette hex value or an arbitrary pixel size. The tokens generated here — --wp--preset--color--primary, --wp--preset--spacing--lg, and so on — are CSS custom properties available to every block, every template, and every stylesheet in the theme. No builder is required to produce them, and no builder license is required to use them.
The styles object in theme.json extends this further. Typography, color, spacing, and border declarations at the block level apply consistently across the editor and the front end:
{
"styles": {
"typography": {
"fontSize": "var(--wp--preset--font-size--base)",
"lineHeight": "1.7"
},
"elements": {
"link": {
"color": { "text": "var(--wp--preset--color--accent)" },
":hover": {
"color": { "text": "var(--wp--preset--color--primary)" }
}
},
"button": {
"color": {
"background": "var(--wp--preset--color--accent)",
"text": "var(--wp--preset--color--base)"
},
"border": { "radius": "0.25rem" }
}
}
}
}
Pseudo-class support for :hover, :focus, :focus-visible, and :active on elements is supported via the Gutenberg plugin and will be available in core from WordPress 7.0. The builder argument that native tooling cannot handle interactive states is already behind the current development cycle.
Block Style Variations As a Component Style System
Builders provide element-level style presets: an “Outline” button variant, a “Card” group style, a “Highlighted” paragraph treatment. These are applied per-element through the builder’s sidebar. The equivalent in a block theme is register_block_style(), introduced in WordPress 5.3 and refined with theme.json style variation support from WordPress 6.2 onward.
The following registers an outline button style and a card group style from a theme’s functions.php:
function aegis_register_block_styles() {
register_block_style(
'core/button',
array(
'name' => 'outline',
'label' => __( 'Outline', 'aegis' ),
)
);
register_block_style(
'core/group',
array(
'name' => 'card',
'label' => __( 'Card', 'aegis' ),
)
);
}
add_action( 'init', 'aegis_register_block_styles' );
The visual properties for each style are declared in theme.json under the styles.blocks key, which keeps all design token references in one place rather than scattering them across separate stylesheets:
{
"styles": {
"blocks": {
"core/button": {
"variations": {
"outline": {
"color": {
"background": "transparent",
"text": "var(--wp--preset--color--primary)"
},
"border": {
"color": "var(--wp--preset--color--primary)",
"width": "2px",
"style": "solid"
}
}
}
},
"core/group": {
"variations": {
"card": {
"spacing": {
"padding": {
"top": "var(--wp--preset--spacing--md)",
"right": "var(--wp--preset--spacing--md)",
"bottom": "var(--wp--preset--spacing--md)",
"left": "var(--wp--preset--spacing--md)"
}
},
"border": {
"radius": "0.5rem",
"width": "1px",
"style": "solid",
"color": "var(--wp--preset--color--surface)"
}
}
}
}
}
}
}
Once registered, these styles appear in the Styles panel for the relevant block in the editor sidebar. A content editor selects “Card” or “Outline” exactly as they would a style preset in any builder — with the distinction that the underlying CSS is scoped to the block, loaded only when that block renders on the page, and defined entirely in standard JSON that any developer can read and modify without a proprietary interface.
Builders advertise saved sections and global templates as a primary differentiator. Breakdance’s Global Blocks and Divi’s Library save design objects that can be reused across pages. This is the correct comparison for WordPress’s two reusable-content systems: synced patterns and template parts.
Synced patterns, introduced as a stable feature in WordPress 6.3, store block markup as a wp_block post type. Any edit to a synced pattern propagates to every instance on the site, matching the behavior of Breakdance’s Global Blocks exactly. A developer registers a pattern category and a set of starter patterns at theme activation; the client manages instances from that point without developer involvement.
Pattern files live in the /patterns folder of a block theme and are auto-registered from WordPress 6.0 onward. The file header controls all registration properties — no functions.php call required:
<?php
/**
* Title: Hero split
* Slug: aegis/hero-split
* Categories: aegis
* Block Types: core/cover
* Viewport Width: 1376
*/
?>
<!-- wp:cover {"align":"full","minHeight":560,"style":{"spacing":{"padding":{"top":"var:preset|spacing|lg","bottom":"var:preset|spacing|lg"}}}} -->
<div class="wp-block-cover alignfull" style="min-height:560px;padding-top:var(--wp--preset--spacing--lg);padding-bottom:var(--wp--preset--spacing--lg)">
<div class="wp-block-cover__inner-container">
<!-- wp:columns {"verticalAlignment":"center","style":{"spacing":{"blockGap":{"left":"var:preset|spacing|lg"}}}} -->
<div class="wp-block-columns are-vertically-aligned-center">
<!-- wp:column -->
<div class="wp-block-column">
<!-- wp:heading {"level":1} --><h1 class="wp-block-heading"><?php esc_html_e( 'Your headline here', 'aegis' ); ?></h1><!-- /wp:heading -->
<!-- wp:paragraph --><p><?php esc_html_e( 'Supporting copy goes here.', 'aegis' ); ?></p><!-- /wp:paragraph -->
<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button --><div class="wp-block-button"><a class="wp-block-button__link wp-element-button"><?php esc_html_e( 'Get started', 'aegis' ); ?></a></div><!-- /wp:button --></div>
<!-- /wp:buttons -->
</div>
<!-- /wp:column -->
<!-- wp:column -->
<div class="wp-block-column">
<!-- wp:image {"sizeSlug":"full","linkDestination":"none"} --><figure class="wp-block-image size-full"><img alt=""/></figure><!-- /wp:image -->
</div>
<!-- /wp:column -->
</div>
<!-- /wp:columns -->
</div></div>
<!-- /wp:cover -->
The Block Types: core/cover header ties this pattern to the cover block’s type, so the inserter presents it as an alternative when a user adds or replaces a cover section. The Block Types: core/template-part/header and core/template-part/footer equivalents tie patterns to the Site Editor’s header and footer replacement interface — the native equivalent of a builder’s “Global Header” design object.
Custom pattern categories are registered programmatically and can be scoped to specific post types:
function aegis_register_pattern_category() {
register_block_pattern_category(
'aegis',
array( 'label' => __( 'Aegis', 'aegis' ) )
);
}
add_action( 'init', 'aegis_register_pattern_category' );
A pattern library scoped to the client’s actual content types — case study layouts, testimonial rows, team grids, call-to-action sections — provides more useful design components than a generic builder library of 200 templates, most of which will never be used.
Extending Core Blocks Without a Builder
The objection that follows this argument is usually about the limits of core block capabilities. The Group block cannot do X. The Image block does not support Y. A builder provides these controls out of the box.
The register_block_type_args filter, available from WordPress 5.6, modifies the registered arguments of any core block without touching the block’s source — including its supports object, which controls which editor controls appear in the sidebar. The following extends the Group block to expose shadow controls and a full border interface:
function aegis_extend_group_block( $args, $block_type ) {
if ( 'core/group' !== $block_type ) {
return $args;
}
$args['supports'] = wp_parse_args(
array(
'shadow' => true,
'__experimentalBorder' => array(
'color' => true,
'radius' => true,
'style' => true,
'width' => true,
),
),
$args['supports'] ?? array()
);
return $args;
}
add_filter( 'register_block_type_args', 'aegis_extend_group_block', 10, 2 );
The same approach enables the duotone filter for blocks where it is not active by default. Adding the filter.duotone support key and specifying the correct CSS selector is sufficient:
function aegis_enable_duotone_on_media_text( $args, $block_type ) {
if ( 'core/media-text' !== $block_type ) {
return $args;
}
$args['supports']['filter']['duotone'] = true;
$args['selectors']['filter']['duotone'] = '.wp-block-media-text .wp-block-media-text__media';
return $args;
}
add_filter( 'register_block_type_args', 'aegis_enable_duotone_on_media_text', 10, 2 );
Per-block stylesheets can be enqueued with wp_enqueue_block_style(), which loads the stylesheet only when the targeted block renders on the current page — matching the on-demand loading behavior builders claim as a performance advantage:
function aegis_enqueue_block_styles() {
wp_enqueue_block_style(
'core/group',
array(
'handle' => 'aegis-block-group',
'src' => get_theme_file_uri( 'assets/blocks/group.css' ),
'path' => get_theme_file_path( 'assets/blocks/group.css' ),
'ver' => wp_get_theme()->get( 'Version' ),
)
);
}
add_action( 'init', 'aegis_enqueue_block_styles' );
The group.css file can contain any CSS that targets the block’s standard class name, wrapping selectors in :root :where() to match the specificity of core block styles and allow user overrides through the Styles interface:
:root :where(.wp-block-group.is-style-card) {
box-shadow: 0 2px 8px rgb(0 0 0 / 0.08);
transition: box-shadow 0.2s ease;
}
:root :where(.wp-block-group.is-style-card:hover) {
box-shadow: 0 4px 16px rgb(0 0 0 / 0.14);
}
None of these techniques requires a builder. None of them requires an additional plugin. They require a developer who has engaged with the platform’s documented extension points rather than reaching for a commercial interface that wraps the same APIs in a proprietary layer.
The Performance Case
Builders impose a fixed performance cost that exists independent of page content. Divi generates framework-level CSS and JavaScript that loads on every page regardless of which modules appear on that page — a characteristic consistently noted across independent benchmarks and confirmed by the platform’s own documentation on its asset loading model.
Bricks takes a different approach, generating per-page CSS from its styling data, which reduces the overhead compared to Divi’s monolithic bundle; the performance gap between Bricks and a lean block theme is narrower, but the structural issue remains the same.
The issue is not simply that builders are slow. The issue is that the performance cost cannot be fully managed because the code is not fully owned. A developer working with Divi cannot remove the Divi framework stylesheet; they can defer it, combine it, and cache it, but they cannot prevent it from loading. A developer working with a block theme can prevent any stylesheet from loading on any page where it is not needed, because the CSS is their own.
wp_enqueue_block_style() loads a stylesheet only on pages where the targeted block renders. A page built from Paragraph, Heading, Image, and Group blocks does not request the Columns block stylesheet, the Cover block stylesheet, or the Query Loop block stylesheet. A builder’s CSS bundle, by contrast, typically contains rules for every module the builder provides — including those not present on the current page.
The effect is visible in Core Web Vitals measurements where block diversity is low. Largest Contentful Paint, one of the three signals Google uses as a ranking factor, is directly affected by render-blocking resources. A block theme that ships only the CSS required for the blocks on the rendered page eliminates an entire category of render-blocking requests that builder-based themes routinely produce.
The Maintenance Case
When a developer hands a builder-built site to a client, the site’s continued function depends on the continued function of the builder. Divi stores its layout data in a combination of serialized post meta and proprietary shortcodes; deactivating Divi without a migration step produces broken pages with raw shortcode text exposed to visitors.
Breakdance stores its layout data in post meta attached to each post and page; deactivating the plugin leaves the site without its presentation layer, with no path to the content that does not involve reinstalling the builder.
Block theme markup is standard WordPress block grammar. <!-- wp:group --> is not a proprietary token. It is an HTML comment following a documented specification. Any WordPress installation with the block editor active can parse, render, and edit it. A developer who takes over a block theme project inherits readable HTML, standard CSS, and a theme.json file. The learning curve is the WordPress platform’s documented APIs — not a specific builder’s proprietary conventions.
The maintenance asymmetry extends to the development environment itself. Etch WP, the most technically ambitious recent entrant, explicitly acknowledges the lock-in problem: it outputs content as native WordPress blocks, which it describes as “data liberation.” That is a real and meaningful distinction from Divi or Breakdance. The client’s content is portable, but the development workflow is not.
Etch WP is the builder a developer uses to build and modify the site. Its companion blank block theme is required for its “Auto Block Authoring” capabilities. Its advanced selector system, template management, and visual interface are Etch-specific. When a client relationship changes, the incoming developer does not inherit a block theme they can edit in their IDE. They inherit an Etch project they need Etch to modify — at Etch’s current pricing, which starts at $199 per year and includes features as paid add-ons above the baseline plan.
This is not a criticism of Etch’s approach, which is technically more principled than any traditional builder’s. It is an observation that “data liberation” is not the same as “development independence.” A block theme built on documented WordPress APIs — register_block_style(), register_block_type_args, wp_enqueue_block_style(), register_block_patterns(), theme.json version 3 — requires no proprietary tool to modify. Any developer with a text editor and familiarity with the Block Editor Handbook can pick it up.
When Builders Become Environments Clients Cannot Use
There is a specific category of WordPress builder that the discourse rarely examines from the client’s perspective. Etch WP, Builderius, Bricks, and Oxygen are marketed at developers — and their feature sets make the target audience unmistakable. These are not tools built for content editors. They are, in varying degrees, integrated development environments that happen to run inside WordPress.
Bricks exposes a Code element that executes PHP, HTML, CSS, and JavaScript directly on the canvas. Custom PHP queries can be written inline inside the Query Loop builder. CSS is managed through a class-based system with custom breakpoints, per-element attribute controls, and direct stylesheet access.
Oxygen carries the same philosophy further: it replaces the theme entirely, gives the developer live PHP and JavaScript editing within the builder interface, and includes a Bloat Eliminator that strips WordPress default assets from the front end. Builderius adds a Monaco-based code editor — the same editor that powers VS Code — with scoped JavaScript panels, a fully synchronized GraphQL query environment for pulling WordPress data, CSS variable management, version control with labeled releases, and a staging and deployment system, while Etch WP positions itself as a visual IDE, surfacing CSS selectors, BEM class generation, and direct HTML manipulation alongside its visual canvas.
Each of these tools addresses a real developer frustration. The code access is genuine, the output is clean, and the professional capability is not in dispute. But every feature added to serve the developer increases the distance between the tool and the client who will eventually be left with the site.
When a client parts ways with the developer who built their site in Bricks, they inherit a Bricks project. The site’s design and layout data lives inside Bricks’ own data structure — not in block markup, not in the theme, not in any format a non-developer can approach. A client who wants to change a section heading, adjust a layout, or understand why a page looks the way it does faces a builder interface designed for someone who is comfortable writing PHP queries and managing CSS class hierarchies.
Content-only editing in Bricks is possible, but it requires the developer to have configured it deliberately. The default state of a Bricks project is a developer’s workspace, not a client’s editing surface.
Why Developers Keep Claiming it Cannot be Done
The first is familiarity. A developer who has spent three years in Bricks or Divi knows where every control is. They know which elements handle which layout problems. They know the workarounds for known issues. Moving to a block theme with the same depth of knowledge requires time investment that produces no immediate client-billable output. The unfamiliarity is real. The conclusion that block themes are therefore inferior is not.
The second is that many developers have not engaged with block themes beyond the defaults. A default Twenty Twenty-Five installation, without custom theme.json configuration, without registered patterns, without extended block supports, without per-block stylesheets, produces limited results. That is not a property of the platform — it is a property of an unconfigured installation.
A default Bricks installation, without configured global classes, without theme styles, without any query loop configuration, produces equally limited results. The fair comparison is between a professionally built block theme and a professionally configured builder setup — and that comparison does not favor the builder.
The developers who have gone through the full process — registering a design-system-complete theme.json, building a pattern library matched to the client’s content model, extending the blocks that needed extension via the documented filter API — consistently report that the result is more maintainable, not less capable.
The Dependency Model and What it Costs Clients
A client who builds their site on Divi is dependent on Elegant Themes’ continued operation, pricing decisions, and compatibility maintenance. The Divi annual license is a line item in the client’s ongoing operating cost. A major version that introduces breaking changes — Divi 5, still in beta as of early 2026, introduces a new rendering engine that is not backward-compatible with Divi 4 layouts — requires developer time to resolve, billed to the client.
The dependency is not only financial. When a client relationship ends and a new developer takes over a Divi or Bricks site, that developer must learn the specific builder’s interface before they can make productive changes. The talent pool for “WordPress developer familiar with Bricks” is narrower than “WordPress developer familiar with the WordPress block editor,” and the latter is the standard that will persist long after any individual builder’s market position changes.
A block theme built on core APIs creates a dependency on competent WordPress development. That is a dependency every WordPress site carries by definition. It does not add a dependency on any specific commercial product’s licensing terms, continued development, or commercial viability.
The honest case against core blocks is not that they cannot produce the result. It is that producing the result requires understanding the platform at a level that takes time to acquire, and that the financial incentive structure of the developer market actively discourages that investment.
A developer who recommends Divi or Bricks earns an affiliate commission and delivers a product quickly. A developer who builds a block theme from first principles earns nothing from the recommendation and invests time in work the client may not immediately recognize as valuable.
The client’s interests and the developer’s short-term incentives are not aligned here. Stating that plainly is the least the developer community owes the clients who fund the whole arrangement.
The Position
Core blocks and a professionally built block theme satisfy every general-purpose client site requirement that third-party builders have claimed as their exclusive territory. The design system is theme.json. The reusable layout components are synced patterns and template parts. The extended block capabilities are register_block_style(), register_block_type_args, and wp_enqueue_block_style(). The accessible, semantic, performant HTML is what core blocks produce by default.
The claim that block themes cannot compete is not a technical assessment. It is a market positioning statement made by people with a financial interest in selling builder licenses, or by developers who have not done the work of learning the platform they are dismissing.
That is not a comfortable position to hold in a community where builder tutorials generate significant traffic and affiliate revenue. It is, however, the one that survives contact with the actual capabilities of WordPress in 2026.
If you have taken a client project from builder dependency to a block theme — what was the specific capability that required the most work to reproduce natively, and what did the solution look like?





Leave a Reply