Building a Professional WordPress Starter Theme with Bedrock, Sage & Tailwind

Introduction

After months of working with different WordPress themes and setups, I decided to build my own starter theme using the Bedrock stack. This isn’t just another theme—it’s a complete architectural approach to WordPress development that aligns more closely with how modern web applications are built.

In this post, I’ll walk you through what I built, why I made these decisions, and why this approach scales far better than traditional WordPress development.


The Problem with Traditional WordPress Development

When I first started building WordPress sites, I leaned on themes like Understrap and Underscores. They’re solid for getting started, but as projects grew, the cracks started to show:

  • Plugin dependencies scattered with no version control
  • Template files cluttered with PHP logic
  • No consistent styling system—everything felt ad hoc
  • Difficult handover between developers
  • No reliable deployment pipeline

The core issue? These setups weren’t designed for scale. They work for small projects, but once complexity increases, maintenance becomes painful.


Enter the Bedrock Stack

Bedrock rethinks how a WordPress project is structured. Instead of the traditional flat setup, it introduces a cleaner, more secure architecture:

├── config/              # Configuration (outside web root)
├── web/                 # Web root
│   ├── app/             # Replaces wp-content
│   ├── wp/              # WordPress core
│   └── index.php        # Entry point
├── vendor/              # Composer dependencies
└── .env                 # Environment variables

This separation is more than just tidy—it’s safer. Sensitive configuration files are kept outside the public directory, reducing exposure in case of server vulnerabilities.


Why Composer Changes Everything

One of the biggest upgrades is Composer integration. Instead of manually installing plugins, everything is defined and version-controlled:

{
  "require": {
    "roots/wordpress": "^6.0",
    "roots/acorn": "^6.0",
    "wpackagist-plugin/wordpress-seo": "^23.0"
  }
}

This gives you:

  • Locked dependency versions
  • One-command updates (composer update)
  • Easy rollbacks
  • Fast onboarding for new developers
  • Full visibility into project dependencies

For client work, this eliminates guesswork and makes maintenance far more predictable.


Blade Templates: Clean Code That Scales

Sage 10 introduces Blade templating, borrowed from Laravel. Instead of mixing logic and markup, you get a clear separation of concerns.

Traditional WordPress:

<?php if (have_posts()): while (have_posts()): the_post(); ?>
  <article>
    <h1><?php the_title(); ?></h1>
    <div><?php the_content(); ?></div>
  </article>
<?php endwhile; endif; ?>

Blade approach:

@extends('layouts.app')

@section('content')
  @while(have_posts())
    @php(the_post())
    <article>
      <h1>{{ get_the_title() }}</h1>
      <div>{{ get_the_content() }}</div>
    </article>
  @endwhile
@endsection

The result is cleaner, more readable, and easier to scale. Developers familiar with modern PHP frameworks can jump in without needing deep WordPress-specific knowledge.


ACF Pro Blocks: Gutenberg Without the Overhead

Instead of building Gutenberg blocks with React, I used ACF Pro to create flexible, server-rendered blocks:

acf_register_block_type([
    'name' => 'hero',
    'title' => 'Hero',
    'render_callback' => function ($block) {
        echo \Roots\view('blocks.hero', [
            'block' => $block,
        ])->render();
    },
]);

This approach keeps things simple:

  • Blocks render with Blade templates
  • No React complexity
  • Faster development workflow
  • Easier collaboration with frontend developers

It’s a practical balance between flexibility and maintainability.


Tailwind CSS: Consistency Without the Bloat

Tailwind CSS provides a utility-first approach to styling. Instead of overriding bulky frameworks, you build exactly what you need:

<h1 class="font-display text-4xl font-semibold text-ink">
  Hello World
</h1>

Design tokens keep everything consistent:

:root {
  --font-display: 'Playfair Display', serif;
  --color-ink: #1a1a1a;
  --color-accent: #8b2500;
}

Update a value once, and it reflects across the entire project. This creates a cohesive design system without unnecessary overhead.


Deployment: From Local to Production

This setup includes a GitHub Actions workflow that automates deployment. When changes are pushed:

  1. Dependencies are installed
  2. Assets are built
  3. Files are deployed to the server
  4. Cache is cleared

No more manual uploads or inconsistent environments—everything is streamlined and repeatable.


Comparing the Architectures

AspectUnderscoresUnderstrapThis Stack
PHP DependenciesManualManualComposer
Template EnginePHPPHP + BootstrapBlade
CSS FrameworkNoneBootstrapTailwind
Block SystemCoreCoreACF Pro
SecurityStandardStandardEnhanced
DeploymentManualManualAutomated
ScalabilityLowMediumHigh
Developer ExperienceBasicGoodExcellent

When to Use This Approach

This stack works best for:

  • Client projects that will evolve over time
  • Agency workflows
  • Portfolio projects showcasing professional development practices
  • Long-term, maintainable websites

It may be overkill for:

  • Simple blogs
  • Quick prototypes
  • Very low-budget builds

Conclusion

This starter theme represents a shift from traditional WordPress development to a more modern, scalable approach.

It brings together better structure, cleaner code, improved security, and a smoother developer experience—all while still leveraging WordPress as a powerful CMS.

For developers looking to level up their workflow, this architecture offers a solid foundation that can handle real-world complexity without falling apart.


Tech Stack: WordPress, Bedrock, Sage 10, Tailwind CSS v4, ACF Pro, Vite, GitHub Actions

Categories:Development

Leave a Reply

Your email address will not be published. Required fields are marked *