Roots launched WP Packages (wp-packages.org), an open source alternative to WPackagist. What it means for Bedrock and Sage projects.
EN

WP Packages by Roots: open source Composer repository for WordPress in 2026

5.00 /5 - (1 votes )
Last verified: May 1, 2026
11min read
Guide
500+ WP projects
Full-stack developer

#Composer-managed WordPress in one paragraph

WP Packages is the second open source Composer repository for the WordPress.org directory. WPackagist has been doing the same job since 2013. The interesting story is not “which mirror wins” but the fact that in 2026 every WordPress shop running CI/CD, multi-environment deploys, or even a single Bedrock project benefits from treating plugins as Composer dependencies. The dashboard install button does not survive contact with a deploy artifact.

The rest of this guide walks the Roots stack (Bedrock, Sage, Trellis), the trade-offs between WP Packages and WPackagist, the premium plugin problem nobody likes to talk about, and the failure modes that trip up teams switching off the dashboard install workflow.

#What Roots actually shipped

In March 2026 the Roots team (Scott Walkinshaw, Ben Word, and contributors) launched WP Packages at wp-packages.org. It mirrors every free plugin and theme from the WordPress.org directory and serves them as a Composer JSON repository.

The launch was not smooth. The project shipped as “WP Composer” on a Tuesday. By Friday Nils Adermann (Composer co-creator, also a contributor to the SemVer spec) had reached out to flag that Composer is a registered trademark held by the Composer project. Roots renamed it to WP Packages over the weekend, kept the existing wp-composer.org URLs answering with a 410 plus deprecation notice, and pushed a Bedrock template update so new projects pointed at the renamed host. This is the kind of incident that would have taken a corporate vendor six weeks of legal review. Open-source projects fix it before the postmortem blog post lands.

#The composer.json that replaces your dashboard

{
  "repositories": [
    {
      "type": "composer",
      "url": "https://wp-packages.org"
    }
  ],
  "require": {
    "php": ">=8.2",
    "wp-packages/advanced-custom-fields": "^6.3",
    "wp-packages/woocommerce": "^9.4",
    "wp-packages/wordpress-seo": "^23.0"
  }
}

composer install then resolves a tree, writes composer.lock, and downloads ZIPs into web/app/plugins/ (Bedrock layout) or wp-content/plugins/ (vanilla WordPress with composer/installers). On a 25-plugin Bedrock project the warm-cache install runs in 30 to 90 seconds. Cold cache, no Composer cache directory, fresh CI runner: 2 to 4 minutes, mostly download time. That number matters once you start chaining composer install into every PR build.

#What self-hosting actually buys you

Self-hosting WP Packages is the one feature WPackagist does not match. Three real scenarios where it pays off:

  • Supply-chain audit. Some agency clients require every dependency to be served from infrastructure they control. With WP Packages you fork the project, mirror it onto an internal endpoint, and your composer.json no longer talks to a third-party host during deploy.
  • Air-gapped CI runners. Jenkins or GitLab Runners inside a customer VPN cannot reach wpackagist.org or wp-packages.org. With self-hosted WP Packages plus a local Composer cache, the deploy pipeline is offline-clean.
  • Custom filtering. A real example: an agency blocked plugins last updated more than 18 months ago from being installable. They forked WP Packages, added the filter at index time, and composer require on a stale plugin now fails with a clear error instead of silently installing abandoned code.

For most teams, WPackagist is fine. The above are the cases where it stops being fine.

#WPackagist: still the default for a reason

WPackagist is run by Outlandish, a UK cooperative. It has been mirroring the WordPress.org directory since 2013 with very few outages. The project’s package naming (wpackagist-plugin/woocommerce, wpackagist-theme/twentytwentyfour) became the de-facto convention; nearly every Bedrock tutorial written before March 2026 assumes WPackagist.

#Side-by-side

PropertyWPackagistWP Packages
Live since2013March 2026
Maintained byOutlandishRoots
Open source repository codeClosedYes (MIT)
Self-hostableNoYes
Vendor prefixwpackagist-plugin/, wpackagist-theme/wp-packages/
Sync methodCron polls WordPress.org SVNCron polls WordPress.org API
Bedrock skeleton defaultYes (today)No (manual swap)
Operational track record12+ yearsA few weeks

#When to switch, when not to

Switch to WP Packages if you need self-hosting, you have already standardised on the Roots stack and prefer single-vendor support, or you have hit a WPackagist sync lag that broke a build and want a second mirror as backup. Stay on WPackagist if your CI is green, your composer.lock is reproducible, and “let us migrate the vendor prefix on 200 client sites” is not on anyone’s roadmap.

The two are not mutually exclusive. Nothing stops you from declaring both repositories and pinning specific plugins to specific mirrors. That is what most agencies will end up doing in practice.

#Bedrock, Sage, Trellis: where Composer actually pays off

The Roots stack is the reason Composer-on-WordPress feels native instead of bolted-on.

#Bedrock: the project layout

Bedrock is a project skeleton, not a framework. What it actually does:

  • Splits WordPress core into web/wp/ (Composer-managed) so wp-config.php is a thin loader instead of the canonical config file.
  • Moves all environment configuration into .env (read by vlucas/phpdotenv) and config/environments/{development,staging,production}.php. The WP_ENV constant drives which environment file loads.
  • Treats web/app/plugins/, web/app/themes/, and web/app/mu-plugins/ as Composer install targets via composer/installers.
  • Ships a mu-plugins/register-theme-directory.php autoloader so composer require on a theme actually registers it with WordPress.

.env is gitignored. Production secrets live in your secret manager, not in wp-config.php. This is the contract that makes WP_DEBUG, ACF Pro license keys, and database credentials per-environment safe instead of “did anyone push the wrong wp-config.php to staging again?”.

composer create-project roots/bedrock my-project
cd my-project
cp .env.example .env
# edit .env with local DB credentials and WP_ENV=development
composer install

#Sage 10 to Sage 11: the migration tax

Sage is the Roots theme. Sage 11 (released 2024) brought Acorn, a Laravel-style container running inside WordPress, plus Blade templates instead of plain PHP. Sage 10 to Sage 11 migrations have specific failure modes worth knowing before you sign up:

  • Acorn breaking changes. Hooked actions registered through Acorn’s service provider mechanism fire later than the same hooks registered in functions.php. Code that assumed init priority 10 may need to move to priority 20 or to a different hook entirely.
  • Blade vs PHP templates. single.blade.php instead of single.php. Old get_template_part calls still work but bypass the Blade pipeline and lose the section/yield mechanics.
  • Asset pipeline. Sage 10 used Bud (Webpack 5 wrapper); Sage 11 moved to Vite. Bud config files are not portable. Your tailwind.config.js is, but watch for PostCSS plugin order differences.

The migration is not push-button. Budget two days for a small theme, a week for anything with custom Gutenberg blocks.

#Trellis: the option you probably do not need

Trellis is Ansible plus Vagrant for local development and remote provisioning. It builds Ubuntu LTS servers with Nginx, MariaDB, PHP-FPM, Redis, and a deploy pipeline. Real talk: Trellis is excellent for shops that own their infrastructure (think 50 to 200 sites on dedicated servers) and overkill for everyone else. If you are deploying to managed WordPress hosting (Kinsta, WP Engine, Pressable), Trellis is not the right tool. If you are running your own DigitalOcean fleet, it is.

#Failure modes nobody mentions in the introduction

These are the four ways composer install ruins someone’s afternoon.

#PHP version drift between local and CI

composer require resolves against the PHP version it sees today. A plugin marked "php": ">=8.2" installs fine on your laptop running PHP 8.3. A staging environment frozen on PHP 8.1 will fail composer install with an unhelpful platform-requirement error. Pin config.platform.php in composer.json to the lowest version any environment runs:

{
  "config": {
    "platform": {
      "php": "8.2.20"
    }
  }
}

This single line saves more deploys than any CI optimization.

#mu-plugins/register.php loaded against the wrong WordPress version

Bedrock’s mu-plugins/ autoloader runs at PHP boot time, before WordPress core is initialized. If you composer update WordPress core to a version that changed WP_PLUGIN_DIR semantics (this happened in WP 6.5), the autoloader can register theme directories that no longer exist. Symptom: white screen on production, fine on staging. Fix: lock roots/wordpress to a known-good minor and bump it deliberately.

#ACF Pro license activation in deploy environments

ACF Pro authenticates its license against advancedcustomfields.com. Deploy artifact builds (think Bitbucket Pipelines, GitHub Actions) run as a fresh container with no DOM, no admin session, and an IP that the ACF license server has never seen. The activation flow that works in wp-admin does not work in a CI runner. Fixes that actually work in 2026:

  • Use the Roots Premium proxy if you are on a Roots organization plan (it brokers ACF Pro and other premium licenses through Composer).
  • Set ACF_PRO_LICENSE as an environment variable read by ACF’s PHP API and skip the dashboard activation flow entirely.
  • Use Composer’s HTTP basic auth (auth.json) to authenticate against ACF’s official Composer endpoint at connect.advancedcustomfields.com.

The first two are the only ones that survive a server migration without manual intervention.

#Composer 2.7 vs Composer 2.6 lockfile incompatibility

Composer 2.7 changed how composer.lock records platform overrides. A composer.lock written by 2.7 fails to install on 2.6 with a misleading “the lock file is not up to date” error. Standardise the Composer version in CI (composer self-update 2.7.7) and document it in your README. Yes, this is annoying. Yes, it has bitten enough teams that Composer 2.8 will warn about it explicitly.

#Premium plugins: the part the docs gloss over

Half the plugins on a real client site are not in the WordPress.org directory. ACF Pro, Gravity Forms, WP Migrate, GP Premium, FacetWP, WP All Import Pro. Composer support varies wildly:

  • ACF Pro: official Composer endpoint at connect.advancedcustomfields.com. Works well, requires auth.json with your license key as the password.
  • Gravity Forms: official Composer support since 2023. License key in auth.json, package name gravityforms/gravityforms.
  • GP Premium (Generate Press): no official Composer endpoint. SatisPress or Roots Premium proxy.
  • WP Migrate Pro (Delicious Brains, now WP Engine): ZIP download with a license-keyed URL. Use a custom Composer repository declaring the package as a package type with the URL inline, or proxy through SatisPress.
  • WP All Import Pro: no Composer endpoint. ZIPs hosted on a license-locked URL. SatisPress or commit the ZIP to a private repository.

Three patterns cover all of these:

  1. Roots Premium (roots.io/premium). A managed Composer proxy that handles licenses for ACF Pro, Gravity Forms, and others. Pricing is individual; for agencies running 50+ sites the math usually works.
  2. SatisPress. A WordPress plugin that turns your own WordPress install into a Composer repository. Install premium plugins normally, expose them via https://your-private-host/satispress/, lock them down with HTTP basic auth.
  3. Private Packagist by packagist.com. Hosted Composer repository with private package support. Costs more than SatisPress, requires zero infrastructure.

Whichever you pick, the rule is: license keys never go in composer.json or auth.json checked into git. They live in environment variables read at install time, or in CI secrets injected into auth.json during the build step.

#CI integration that survives reality

A working deploy pipeline:

# .github/workflows/deploy.yml (excerpt)
- name: Set up PHP 8.2
  uses: shivammathur/setup-php@v2
  with:
    php-version: '8.2'
    tools: composer:2.7

- name: Cache Composer
  uses: actions/cache@v4
  with:
    path: ~/.composer/cache
    key: composer-${{ hashFiles('composer.lock') }}

- name: Install
  run: composer install --no-dev --optimize-autoloader --prefer-dist --no-interaction
  env:
    COMPOSER_AUTH: ${{ secrets.COMPOSER_AUTH_JSON }}

- name: Deploy artifact
  run: rsync -avz --delete --exclude='.git' --exclude='node_modules' ./ deploy@host:/var/www/html/

Three rules that will save you debugging time:

  • Never run composer update in CI. Update locally, commit the new composer.lock, push. CI runs composer install against the exact lockfile.
  • Cache ~/.composer/cache keyed on composer.lock hash. Cold installs go from 4 minutes to 30 seconds.
  • Inject auth.json from a secret. COMPOSER_AUTH env variable is read by Composer natively. Never commit licensed credentials.

#What changed in WordPress culture in 2026

Composer-on-WordPress used to be a Roots-shop thing. In 2026 it is the default for any agency or in-house team that ships to more than one environment. Three signals from the wider ecosystem:

  • WordPress.org plugin submissions cleared 500 per week in early 2026, up from 100 to 150 weekly through 2022 to 2024 (source: weekly Plugin Review Team reports). Most of the new volume is AI-assisted code. The Plugins Team is hiring volunteer reviewers; the directory’s quality bar is under strain.
  • Both Kinsta and WP Engine added native Composer build support to their Git push deployment in late 2025. The “managed WordPress host that ignores composer.json” category is shrinking.
  • WP-CLI 2.10 added wp composer subcommands that wrap composer install, composer update, and lockfile validation. Composer is becoming part of WP-CLI’s official surface area.

The lesson for plugin-as-dependency management: the tooling is maturing faster than the WordPress.org directory’s review capacity. A self-hostable mirror like WP Packages is more useful in this context than it would have been five years ago, when the directory was a closed garden everyone trusted by default.

#Last updated: 2026-04-01

Need help migrating a site to Bedrock or setting up a Composer-driven deploy pipeline? See our WordPress development services.

Next step

Turn the article into an actual implementation

This block strengthens internal linking and gives readers the most relevant next move instead of leaving them at a dead end.

Want this implemented on your site?

If you want to convert the article into a working site improvement, redesign, or build plan, I can define the scope and implement it.

Related cluster

Explore other WordPress services and knowledge base

Strengthen your business with professional technical support in key areas of the WordPress ecosystem.

Article FAQ

Frequently Asked Questions

Practical answers to apply the topic in real execution.

SEO-ready GEO-ready AEO-ready 5 Q&A
What is WP Packages by Roots?
WP Packages (wp-packages.org) is an open source Composer repository that mirrors the WordPress.org plugin and theme directory. You require packages with the wp-packages/ vendor prefix in composer.json instead of downloading ZIPs from the dashboard.
How is WP Packages different from WPackagist?
Both mirror the WordPress.org directory for Composer use. WP Packages is open source and self-hostable, runs on Roots infrastructure, and uses the wp-packages/ vendor prefix. WPackagist has been the community standard since 2013, is maintained by Outlandish, and uses the wpackagist-plugin/ and wpackagist-theme/ prefixes. Both pull from the same upstream directory.
Why was WP Composer renamed to WP Packages?
Nils Adermann, co-creator of Composer, contacted Roots after launch to flag that Composer is a registered trademark and the name could cause user confusion. Roots renamed the project to WP Packages within days, kept the same package URLs working with a deprecation notice, and moved to wp-packages.org.
Should I switch from WPackagist to WP Packages?
There is no urgent reason if WPackagist works for your team. Switch when you need to self-host (air-gapped CI, supply-chain audit), when you are already deep in the Roots stack, or when WPackagist has had a sync delay that broke your build. Otherwise the migration cost outweighs the benefit.
Does WP Packages work with Bedrock?
Yes. Both repositories work the same way in Bedrock. You add wp-packages.org or wpackagist.org as a Composer repository in composer.json and declare plugins under the matching vendor prefix. The roots/bedrock skeleton ships with WPackagist preconfigured today; swapping it for WP Packages is a two-line change.

Need an FAQ tailored to your industry and market? We can build one aligned with your business goals.

Let’s discuss

Related Articles

WordPress 7.0 with AI Client vs Astro 6 after Cloudflare acquisition. Speed, cost, SEO and security comparison. My take after 20 years as a WP developer - when to migrate and when to stay.
wordpress

WordPress 7.0 vs Astro 6 after Cloudflare acquisition - who wins in 2026?

WordPress 7.0 with AI Client vs Astro 6 after Cloudflare acquisition. Speed, cost, SEO and security comparison. My take after 20 years as a WP developer - when to migrate and when to stay.

Astro 5 or Next.js 15 - which framework should you choose in 2026? In-depth comparison of performance, architecture, use cases, and when to use each for WordPress Headless projects.
wordpress

Astro 5 vs Next.js 15: Complete Technical Comparison 2026

Astro 5 or Next.js 15 - which framework should you choose in 2026? In-depth comparison of performance, architecture, use cases, and when to use each for WordPress Headless projects.

How to build a fast e-commerce store with Headless WooCommerce and Astro. Architecture deep-dive, performance comparison, and step-by-step implementation guide.
wordpress

Headless WooCommerce with Astro: The E-commerce Performance Guide 2026

How to build a fast e-commerce store with Headless WooCommerce and Astro. Architecture deep-dive, performance comparison, and step-by-step implementation guide.