The hidden costs of building too many custom blocks

Over the past few weeks, I worked on two very different client projects, but they had the same problem.

Both websites use the custom block editor and are regularly updated. However, they were struggling with technical debt.

This means that decisions made in the past made it harder to add new features and made the CMS messy and difficult to use.

The main reason for these problems? Custom blocks.

Why do we build custom blocks?

There are three reasons why developers create custom blocks:

  1. Specific client needs for functionality.
  2. Design requirements.
  3. Improved user experience.

When we started out with the block editor in 2018, all three were valid reasons. But now, six years later, WordPress is very different.

With features like patterns and block bindings, we need fewer and fewer custom blocks. However, this is not yet recognized by all WordPress developers or clients.

Once you master building native custom blocks, creating a block doesn’t take much time. Especially when these are monolithic modules that represent an entire section of a page.

This is a screenshot of the Unlocking the Digital Evolution: Navigating the Gutenberg Era presentation at WordCamp US.

Back in 2018, when I built my first block-based website, every block was precisely like this:

  • Use PHP to render the editor preview and the front end.
  • Implement sidebar controls to configure the block.

It’s essentially a glorified shortcode adapted to the block editor. And there’s nothing inherently wrong with this approach–if it’s not your only approach.

Indeed, I teach this in my block development course, and it’s a great way to start building custom blocks. It’s a great way to migrate websites with classic themes to the block editor without rebuilding everything.

But it shouldn’t be a default, especially if you are building block themes rather than hybrid ones. Every block has a cost.

The hidden costs of custom blocks

When discussing building blocks this way, maintainability and scalability are brought up often.

In other words, we want to be able to build as many different pages as possible, and we want any changes made to blocks to reflect across the entire site.

And yes, dynamic custom blocks fulfill that need. Up to a point.

Usability and interface concerns

Yes, the Query Loop block without any patterns or variations is challenging for non-technical users. However, it allows users to query all types of content through one block.

If you build specific blocks for each type of content and different blocks for different queries, you end up with a lot of blocks. Add in different design variations, and you’re not really solving the problem that the Core Query Loop has: lots of options.

Is an interface like the one above really more straightforward to use? I’ve come to doubt this, especially if you combine different layout types (regular grid, irregular grid, slider, etc.) into one block because the data source is the same.

This does not mention the number of blocks to sift through as a user. Finding the right one is a challenge if your website has over 20 custom blocks, often with poor naming and vague icons.

From my own experience and also from talking to WordPress users, overwhelm is a genuine concern, and custom blocks do not really help to solve the problem.

If you have followed me for some time, you know that I am a proponent of removing every customization option that your users don’t need. So, let’s not solve the issue of Core WordPress overwhelming users, only to confuse them with dozens of custom blocks instead.

Technical and maintenance costs

One of the websites I worked on used a basic card design:

And variations of this card show up all over that website. All these variations use the same PHP template. So when you open this file, this is what you see:

This variables are then fed into a confusing barrage of if/else statements. In the end the whole file isn’t longer than maybe 350 lines. But you still have no clue about the logic behind it, or how these arguments map to blocks, or even interface elements in these blocks.

And this is not to forget the cost of essential maintenance that every website needs. Custom blocks, unlike some preconceived notions, need very little attention. And when they need maintenance updates (like replacing deprecated components), these are minute changes.

But the numbers work against you. Even if you can make a change in 15 minutes, if you have 20 blocks to change, this will take 5 hours. I work on multiple client websites that have lots of blocks, and it all adds up. Even worse, you’ll have to bill the client these hours, and they don’t really get anything new.

Content portability challenges

There is a preconceived notion that building patterns mix content and design and that this is “dirty.” Custom blocks, on the other hand, are “clean” because they separate content from design.

The issue is that this “separation” does not bring the benefits that developers expect.

Last month, I worked on a client website that had this exact issue. It started years ago when the site was first built.

First, there was a block that allowed users to query for blog posts, and three of these posts would be shown in a grid.

Then, the need came up to have a two-column and one-column version and additional query controls. This was implemented as a new block, as extending the first block would have been difficult.

But that meant that if a user wanted to change from a three-column blog post display to a two- or one-column display, they needed to add a new block, configure it, and then delete the old one.

Something that, with a Query Loop, you could do with a few clicks.

And now, the requirement came in to have a carousel display, which was implemented as yet another custom block.

So, while technically, the content (attributes) and the display (PHP templates) of dynamic blocks are separate, this doesn’t mean infinite flexibility. In reality, there are limits to the flexibility of custom blocks. And also how much you can put into a single block.

As each block is an independent entity, migrating from one block type to another is as difficult as if you were to use Core blocks composed into a pattern.

Better practices for block-based website building

So, no more monolithic dynamic blocks? No. As usual, the appropriate answer is not in the extremes.

And if you are heavily relying on this type of block, whether native or built using ACF, don’t be rash.

But consider these alternatives next time you want to build yet another one-off block.

Leverage Core blocks

Block bindings are relatively new, but I’ve seen the need for small one-off blocks reduce significantly.

One example I am currently working on is a buy button for my new course sales pages. This block has been around for a while, and of course, I implemented it as a custom block.

It was quick and easy to assemble, but I took many shortcuts. Again, it’s one of these “shortcodes in the block editor”-blocks we talked about.

But there’s nothing custom about the block’s display at all. The custom part all relates to the data injected into the block. So, by creating a custom block binding, I can use a Core block with all the upsides that this entails, but not downsides.

Prefer patterns or inner blocks over monoliths

When I talk about a monolithic block, I mean that it’s one big block that makes up the entire module, like the Media & Text block in Core.

But it’s quicker and more flexible to compose the wanted feature set and design out of default blocks.

This could be in the form of a partially synced pattern or, if you want to use some block-specific features, a wrapper block that allows you to use inner blocks.

Want a read more link? Add it in! Don’t want an image? Just remove it.

You’ll see that this is a lot more versatile than monoliths. It also leads to an easier-to-understand user interface.

Build for reusability

A couple of weeks ago, my colleagues and I discussed open-sourcing some of the custom blocks we built for client projects.

As we reviewed the projects, it became clear to me that we had solved the same problems repeatedly.

Accordions are a classic example. They all work the same, but they look differently. So, we ended up implementing essentially the same thing over and over in slightly different flavors.

The issue is with how blocks are built. An accordion block will have a wrapper and item blocks, but all the rest, especially the markup and styling, is project-specific.

What we need are more modular blocks. The Team51 at WordPress.com build such a version.

It divides the block up further, with dedicated blocks for the trigger and the content. The trigger block has some choices for icons built-in. Rather than assuming functionality for opening and closing, this is configurable.

So, the challenge is to build fewer blocks but better blocks.

Blocks that not only solve one particular need on one specific project. But blocks that you can use across projects.

Conclusion

Custom blocks are a fantastic tool for extending WordPress and something you should know how to build. But like any tool, they need to be used wisely.

By balancing unique needs with scalability, you can avoid the pitfalls of over-customization and keep your projects maintainable and future-proof.

Remember, the goal isn’t to avoid custom blocks entirely but to use them strategically—to save time, reduce headaches, and deliver robust solutions for your clients or projects.

Take a moment to review your current block strategy: Are there blocks you could simplify, consolidate, or replace with reusable patterns? Minor adjustments now can save you countless hours down the road.

If you’ve faced challenges with custom blocks or have strategies that work well, I’d love to hear your story. Hit reply, and let’s share ideas!

Fränk Klein Avatar