roots/bedrock (~6.5k stars) is the WordPress boilerplate that treats WP like a modern PHP app: Composer dependencies, .env-based config, and a folder layout that keeps the web root leaner than a default unzip of WordPress. If you have ever committed wp-config.php with database passwords, dumped the entire wp-content/plugins folder into Git as zip files, or struggled to reproduce a client's server on your laptop, Bedrock is the structural fix.

Why Bedrock exists

Stock WordPress mixes core files, plugins, uploads, and config in ways that fight version control and twelve-factor deploy practices. Bedrock's goals:

  • Install WordPress core and plugins via Composer (version pins, lock file, reproducible builds)
  • Keep secrets and environment values out of Git using .env
  • Separate web root from application code for tighter security boundaries
  • Improve deployability to staging and production with the same artifact
  • Make "this project is a Git repo" the default, not an afterthought

Bedrock does not replace WordPress — it reorganizes how you install, configure, and ship it. The admin experience editors see is still familiar wp-admin.

Who Bedrock is for

  • Agencies shipping multiple client sites with similar deploy pipelines
  • Developers already using Composer in PHP projects
  • Teams deploying to Kinsta, SpinupWP, Forge, or custom VPS with Git-based workflows
  • Projects that need environment-specific config (local, staging, production) without editing tracked files

When NOT to use Bedrock

  • Shared hosting with no SSH/Composer — Bedrock expects CLI access for installs and updates
  • WordPress.com or fully managed platforms that forbid custom directory layouts
  • One-click MAMP sites for learning — classic installs are simpler for tutorials
  • Teams with zero PHP tooling comfort — the learning curve is real

Get a project running

Bash
composer create-project roots/bedrock my-site
cd my-site
cp .env.example .env
# Edit DB credentials and WP salts in .env
composer install

Point your web server (or DDEV, Lando, or Local) at Bedrock's web/ directory as documented in the README — it is not always the project root. Misconfigured document roots are the most common first-day Bedrock mistake.

Folder layout (mental model)

Bedrock moves WordPress core into web/wp, keeps plugins and themes under web/app/, and stores configuration in config/ files that read from .env. Uploads land in web/app/uploads. Understanding this split matters when you debug paths, symlink plugins, or write deploy scripts.

Bedrock + Sage + WP-CLI (professional stack)

Common professional stack:

  1. Bedrock for the install, Composer lock file, and environment config
  2. Sage as the theme (also Composer-installed)
  3. WP-CLI for search-replace, user creation, migrations, and CI scripts
  4. Query Monitor on local/staging for performance debugging

Install plugins via Composer when packages exist on WPackagist; fall back to manual placement in web/app/plugins/ for premium or custom plugins.

Environment configuration workflow

  1. Copy .env.example to .env per environment (never commit .env).
  2. Set DB_*, WP_HOME, WP_SITEURL, and authentication keys.
  3. Use WP_ENV to toggle debug settings in config/environments/.
  4. Run wp search-replace when moving between URLs after deploy.

Gotchas

  • Document root — must point at web/, not the repo root.
  • Plugin updates — Composer-managed plugins update via composer update, not always the wp-admin updater.
  • Premium plugins — often need private Composer repositories or manual installs.
  • Bedrock is not a hosting panel — you still configure nginx/Apache, SSL, and cron.

Content editing after deploy

Bedrock solves infrastructure; it does not solve "update 40 ACF hero titles before launch." When the site uses Advanced Custom Fields heavily, add Quickfields Bulk Editor for ACF so editors can sheet-edit text fields with autosave. Full walkthrough: Quickfields blog post. CSV and image workflows: Quickfields Pro.

Bedrock vs classic WordPress install

AspectClassicBedrock
Core installManual download / installerComposer package
Secretswp-config.php (often in Git).env (gitignored)
Pluginswp-admin zip uploadsComposer + WPackagist
Deploy reproducibilityVariablecomposer.lock driven

FAQ

Is Bedrock a framework like Laravel? No — it is a WordPress directory layout and config pattern, not a replacement CMS.

Can I migrate an existing site to Bedrock? Yes, but it is a structured migration (files, paths, config) — plan downtime and test on staging.

Does Bedrock work with headless? Yes — pair with WPGraphQL for decoupled front ends.

What about WordPress multisite? Bedrock supports multisite with additional configuration documented in the Roots guides — not as one-click as single-site, but viable for network installs managed by experienced teams.

How do updates work? WordPress core updates via Composer (composer update roots/wordpress or similar per your composer.json). Always test core bumps on staging with Query Monitor watching for deprecated hook usage in custom plugins.

Security and deployment mindset

Bedrock's web-root separation means only web/ is publicly servable — application code and .env sit outside the document root when configured correctly. Combine that with disallowing file editing in production (DISALLOW_FILE_EDIT), managed plugin updates through Composer lock files, and automated backups before WP-CLI migrations. Bedrock is not a security silver bullet, but it removes entire classes of "accidentally committed secrets" and "plugins uploaded via zip on production" failures that classic installs tolerate.

When onboarding new developers, document your Composer commands, required PHP extensions, and where premium plugins live — Bedrock rewards teams that treat README files as living deploy runbooks, not afterthoughts.

Repo

github.com/roots/bedrock