WordPress non è elegante e forse **non prova nemmeno a esserlo**.

Eppure continua a vincere nei progetti in cui contano ecosistema, plugin, competenze disponibili, integrazioni già pronte e poco attrito per il cliente.

Il punto, nel 2026, non è decidere se WordPress sia bello. Il punto è decidere se puoi governarlo senza affidarti alla fortuna.

È qui che entra in gioco [Roots](https://roots.io).

Questo articolo parla prima di tutto a chi WordPress lo consegna per mestiere: agenzie, studi e team tecnici che hanno clienti veri, budget veri e siti che dopo il lancio non possono diventare oggetti misteriosi.

E parla anche alle aziende che hanno costruito un asset importante su WordPress, magari con un builder, e iniziano a farsi una domanda scomoda: quanto controllo abbiamo davvero su qualcosa che dovrebbe portarci contatti, vendite o autorevolezza?

Dopo anni passati a sviluppare con [Laravel](https://laravel.com), dove una cartella ha quasi sempre il nome che dovrebbe avere e i _coding standard_ non sembrano un capriccio, sviluppare con il _core_ di WordPress richiede ancora un certo autocontrollo: funzioni interminabili, `snake_case` ovunque, array associativi come forma di vita dominante, _hook_ sparsi e _type hint_ distribuiti con prudenza monastica, manco si pagassero a peso.

Non lo dico per snobismo. Lo dico perché chi fa consulenza tecnica deve separare due cose: il gusto personale e la convenienza del progetto.

Il gusto personale mi porta spesso altrove. In **Encodia**, quando il progetto ce lo permette, usiamo volentieri **Statamic**: è _Laravel-native_, ha una qualità del codice superiore e spesso è la scelta più naturale quando il cliente può accettare un CMS moderno senza tutta l'eredità storica di WordPress.

La convenienza del progetto, però, qualche volta porta ancora dritta a WordPress: un plugin chiave, un'integrazione pre-esistente, una redazione già formata. Un modello di business che poggia su quell'ecosistema e non vuole, giustamente, ricominciare da zero.

Quando succede, ho una regola: niente WordPress trattato come un sito caricato via FTP!

Se entra in un progetto serio, entra come applicazione PHP seria: dipendenze versionate, ambienti separati, _deploy_ reversibili, configurazione leggibile, responsabilità chiare.

**Roots** serve esattamente a questo.

Non trasforma WordPress in Laravel. Però lo avvicina a quel modo di lavorare: Composer, configurazioni leggibili, _template_ meno primitivi, ambienti replicabili, _deploy_ che non dipendono dalla fortuna.

La tesi è semplice: Roots non rende WordPress moderno per magia. Lo rende governabile. E in molti progetti la differenza non è estetica, è economica.

## Cosa compra davvero chi sceglie Roots

Quando in una riunione mi lascio andare e dico Bedrock, Sage, Trellis, Composer o _deploy_ atomico, vedo spesso lo stesso sguardo: tecnico che parla tecnico.

Tradotto meglio: con Roots non stai comprando una mania da sviluppatore. Stai comprando controllo.

Controllo sugli aggiornamenti. Controllo sugli ambienti. Controllo sul giorno, inevitabile, in cui qualcosa si rompe e bisogna capire chi ha cambiato cosa, quando, e come tornare indietro senza trasformare la produzione in un laboratorio.

Roots è un'organizzazione _open source_ indipendente che dal 2011 produce strumenti per usare WordPress come si userebbe una vera applicazione PHP: Composer per le dipendenze, Git per il versionamento, ambienti separati per sviluppo, _staging_, UAT e produzione, _deploy_ atomici, server descritti in YAML.

Dal punto di vista di un cliente o di un'azienda, il valore è meno astratto di quanto sembri:

- **meno sorprese in produzione**: gli ambienti sono coerenti _by design_, quindi "sulla mia macchina funziona" smette di essere una frase accettabile;
- **_rollback_ in pochi secondi** se un _deploy_ va storto, perché prima o poi succede a tutti;
- **onboarding più rapido** per chi arriva da Laravel o da progetti PHP moderni;
- **costi di _hosting_ prevedibili**, perché con Trellis puoi stare su VPS solide senza consegnarti a un fornitore unico;
- **tracciabilità vera**: aggiornamenti, plugin, tema e configurazione passano da Git e finiscono in un `composer.lock`;
- **meno dipendenza dall'eroe di turno**, quello che "sa dove mettere le mani" ma non ha lasciato una riga di documentazione.

Non è romanticismo tecnico. È riduzione del rischio.

## Roots, pezzo per pezzo: Bedrock, Sage, Trellis, Acorn e WP Packages

Roots è una famiglia di strumenti. Puoi usarli insieme, oppure prendere solo il pezzo che serve. Il punto, però, è capire la logica complessiva: riportare ordine in un ecosistema che per cultura storica ha tollerato troppo a lungo il "si è sempre fatto così".

### 1. Bedrock: WordPress smette di vivere nel caos

[Bedrock](https://roots.io/bedrock/) è un _boilerplate_ che riorganizza WordPress in modo finalmente sensato e gestisce tutto via Composer: _core_, plugin e temi.

```text title="Struttura Bedrock" showLineNumbers=false
example.com/
├── composer.json          # tutte le dipendenze, anche il core WordPress
├── config/
│   ├── application.php    # config "Laravel-style"
│   └── environments/
│       ├── development.php
│       └── staging.php
├── web/
│   ├── app/               # wp-content (themes, plugins, mu-plugins)
│   ├── wp/                # core di WordPress gestito da Composer
│   └── wp-config.php
└── .env                   # credenziali fuori dal repository
```

Un `composer.json` di progetto, oggi, dovrebbe già ragionare con i namespace di WP Packages:

```json title="composer.json"
{
  "require": {
    "php": ">=8.3",
    "composer/installers": "^2.3",
    "vlucas/phpdotenv": "^5.6",
    "roots/bedrock-autoloader": "^1.0",
    "roots/wordpress": "^6.7",
    "wp-plugin/wordfence": "^7.11",
    "wp-plugin/wp-mail-smtp": "^4.2"
  },
  "repositories": [
    {
      "type": "composer",
      "url": "https://repo.wp-packages.org"
    }
  ]
}
```

Da qui in avanti, aggiornare WordPress e i plugin non significa più entrare in bacheca, cliccare un bottone e sperare. Significa aggiornare dipendenze, verificare il `composer.lock`, passare da CI, fare _deploy_.

Sembra più lento solo se guardi il singolo click. Se guardi il ciclo di vita di un progetto, è l'opposto.

Bedrock `v1.29` ha alzato la versione minima di PHP alla 8.3.x e include il supporto **Pest** _out of the box_. È un segnale culturale prima ancora che tecnico: anche in WordPress i test devono smettere di essere una cosa strana.

### 2. Sage: un tema WordPress che non sembra scritto nel 2010

[Sage](https://roots.io/sage/) è uno _starter theme_ per scrivere temi WordPress con strumenti che altrove sono normali da anni:

- **Blade** come motore di _template_, lo stesso approccio che chi usa Laravel riconosce subito;
- **Tailwind CSS** preconfigurato;
- **Vite** per l'_asset bundling_, con il Roots Vite Plugin aggiornato e più veloce;
- supporto al _block editor_ con `theme.json` generato dalla configurazione Tailwind.

Un loop in Sage si legge così:

```blade title="resources/views/index.blade.php"
{{-- resources/views/index.blade.php --}}
@extends('layouts.app')

@section('content')
    @while(have_posts()) @php(the_post())
        <article @php(post_class('mb-12'))>
            <header>
                <h2 class="text-2xl font-bold">
                    <a href="{{ get_permalink() }}">{!! get_the_title() !!}</a>
                </h2>
                <time datetime="{{ get_the_date('c') }}" class="text-sm text-stone-500">
                    {{ get_the_date() }}
                </time>
            </header>

            <div class="prose mt-4">
                {!! get_the_excerpt() !!}
            </div>
        </article>
    @endwhile

    {!! get_the_posts_navigation() !!}
@endsection
```

Non è solo questione di sintassi più gradevole. È che un tema smette di essere una cartella piena di compromessi e diventa un pezzo di applicazione con struttura, asset pipeline e convenzioni decenti.

Chi arriva da Laravel non ha bisogno di traduzioni. Chi arriva dal WordPress "classico" all'inizio protesta, poi scopre che non dover rincorrere `get_template_part()` in mezzo progetto è una forma concreta di benessere.

### 3. Trellis: deploy e server sotto controllo

[Trellis](https://roots.io/trellis/) è uno _stack_ LEMP basato su Ansible. Descrivi il sito in YAML, lanci il provisioning, ottieni un server Ubuntu 24.04 con Nginx, PHP 8.3, MariaDB, Let's Encrypt, fail2ban, Redis e il resto dell'infrastruttura che in un progetto serio dovrebbe essere esplicita, non ricordata a memoria da qualcuno.

```yaml title="trellis/group_vars/production/wordpress_sites.yml"
# trellis/group_vars/production/wordpress_sites.yml
wordpress_sites:
  cliente.it:
    site_hosts:
      - canonical: davideprevosto.it
        redirects:
          - www.davideprevosto.it
    local_path: ../site
    repo: git@github.com:davideprevosto/davideprevosto.it.git
    branch: main
    multisite:
      enabled: false
    ssl:
      enabled: true
      provider: letsencrypt
    cache:
      enabled: true
    xmlrpc:
      enabled: false
```

Il _deploy_ è una riga:

```bash
$ trellis deploy production
```

Dietro quella riga, però, succedono cose importanti: Trellis crea una nuova _release_, lancia `composer install`, aggiorna il _symlink_ `current/` in modo atomico. Se qualcosa va storto, `trellis rollback production` torna alla _release_ precedente in pochi secondi.

Questa è la parte che spesso il cliente capisce solo dopo il primo incidente evitato.

Le versioni recenti hanno aggiunto **HTTP/3**, _hardening_ WordPress _runtime_ _opt-in_, sessioni PHP su Redis e compatibilità Ansible 2.19. Da qualche tempo Trellis ha mandato in pensione Vagrant e VirtualBox a favore di **Lima** per lo sviluppo locale: meno peso, meno attese, meno scuse.

Trellis gira su qualsiasi VPS Ubuntu. **Zero _vendor lock-in_.** Domani vuoi spostare tutto da DigitalOcean a Hetzner? Cambi un IP, rilanci `trellis provision`, sistemi DNS e ci sei.

Questa libertà sembra un dettaglio finché non ti serve davvero.

### 4. Acorn: Laravel dentro WordPress, dove serve

[Acorn](https://roots.io/acorn/) è il ponte fra il mondo WordPress e il modo in cui molti sviluppatori PHP moderni ragionano già da anni. Con Acorn, in un progetto WordPress puoi usare il _container_ di servizi di Laravel, le _facade_, il _routing_, Eloquent, le View, i _config provider_.

Non trasforma WordPress in Laravel. E per fortuna: sarebbe una promessa sbagliata.

Fa una cosa più concreta: ti permette di scrivere certe parti dell'applicazione con strumenti più solidi, senza uscire dall'ecosistema WordPress.

Una rotta "virtuale" in Acorn, utile per _health-check_, _webhook_ o _endpoint_ REST _custom_ che non hanno senso come pagine di WordPress:

```php title="app/Routes/web.php"
// app/Routes/web.php
use Illuminate\Support\Facades\Route;

Route::get('/health', function () {
    return response()->json([
        'status' => 'ok',
        'php'    => PHP_VERSION,
        'wp'     => get_bloginfo('version'),
        'env'    => wp_get_environment_type(),
    ]);
});
```

Un _service provider_ che chiunque abbia lavorato con Laravel riconosce senza manuale:

```php title="app/Providers/AppServiceProvider.php"
// app/Providers/AppServiceProvider.php
namespace App\Providers;

use Roots\Acorn\ServiceProvider;
use App\Services\HubSpotClient;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(HubSpotClient::class, function () {
            return new HubSpotClient(
                token: config()->string('services.hubspot.token'),
            );
        });
    }
}
```

L'ultima _major_ (**Acorn v6.1**) è del 26 aprile 2026. Tra i pacchetti ufficiali segnalo `roots/acorn-ai`, che integra la **WordPress Abilities API** per i _workflow_ di intelligenza artificiale, e `roots/acorn-post-types`, che permette di dichiarare _custom post type_ e tassonomie in modo dichiarativo.

Qui il vantaggio non è scrivere codice "più bello". È scrivere codice che un team può leggere, testare e mantenere senza dover ricostruire ogni volta il pensiero di chi lo ha scritto.

### 5. WP Packages: quando il controllo della filiera diventa tecnico

Questa è la novità più interessante del 2026, perché non riguarda solo la comodità. Riguarda il controllo dell'infrastruttura.

[WPackagist](https://wpackagist.org) è stato per anni il _mirror_ Composer di fatto per plugin e temi del repository ufficiale di WordPress. Era un servizio della _community_, gestito dall'agenzia Outlandish. A marzo 2026 è stato **acquisito da WP Engine**.

La domanda non è ideologica. È pratica.

Ti va bene che un pezzo di infrastruttura così centrale, quello che risolve le dipendenze di moltissimi progetti WordPress moderni, sia controllato da una singola _corporation_ a partecipazione _private equity_?

Per alcuni la risposta è sì. Per altri è: non ci avevo mai pensato, ma adesso che lo dici no, non mi piace.

Roots ha risposto con un'alternativa indipendente: **[WP Packages](https://wp-packages.org/)**. È nato come WP Composer, poi rinominato a marzo 2026. I numeri dichiarati sono interessanti perché non sono solo marketing:

- **circa 17 volte più veloce** sul _resolve_ a freddo, grazie al supporto pieno del protocollo `metadata-url` di Composer 2;
- aggiornamenti **ogni 5 minuti**, invece di finestre molto più lunghe;
- `composer.lock` riproducibili anche per plugin senza _tag_, con _pinning_ a revision SVN;
- statistiche pubbliche, _status page_ in tempo reale, codice _open source_.

La migrazione è quasi banale. Cambiano i _namespace_: `wpackagist-plugin/*` diventa `wp-plugin/*`, `wpackagist-theme/*` diventa `wp-theme/*`. Il repository Composer punta a `https://repo.wp-packages.org`.

```bash
$ composer remove wpackagist-plugin/woocommerce

$ composer config --unset repositories.wpackagist \
  && composer config repositories.wp-packages composer https://repo.wp-packages.org

$ composer require wp-plugin/woocommerce
```

Per un progetto nuovo nel 2026, partire direttamente da WP Packages è la scelta più pulita. Per un progetto esistente, è una migrazione da valutare con calma, ma difficilmente la ignorerei: build più veloci, lock file più affidabili, meno dipendenza da un attore solo.

Non è una questione da puristi. È gestione del rischio di filiera.

## Radicle: la scorciatoia seria

[Radicle](https://roots.io/radicle/) è il punto d'ingresso consigliato da quando è stato lanciato nel 2024. È una distribuzione "_opinionated_" (yeah) che combina **Bedrock + Sage + Acorn + Trellis** in una struttura già allineata al _folder layout_ di Laravel, con `public/` come _document root_ al posto di `web/` (presto Bedrock si adeguerà anche a questo particolare).

```text title="Struttura Radicle" showLineNumbers=false
progetto/
├── app/                  # codice applicativo (providers, models, jobs)
├── bootstrap/
├── config/
├── public/               # document root
│   ├── content/          # wp-content (themes, plugins)
│   └── wp/               # core
├── resources/
│   ├── views/            # template Blade
│   └── styles/
├── routes/
├── storage/
├── trellis/              # config server, se serve
├── composer.json
└── .env
```

Per chi viene da Laravel, il carico cognitivo è basso. Per chi viene da WordPress classico, la curva c'è. Ma su progetti di un certo livello è una curva che si ripaga.

Per crearne uno nuovo:

```bash
$ composer create-project roots/radicle nuovo-progetto
$ cd nuovo-progetto
$ cp .env.example .env
$ wp acorn radicle:install
```

Versione corrente: **v2.6.0** (aprile 2026). Un dettaglio non secondario: Radicle è **a pagamento** per l'uso commerciale. A me sembra una cosa sana. Se una toolchain mi fa risparmiare giorni di lavoro e abbassa il rischio operativo di un progetto, il problema non è pagarla. Il problema è illudersi che l'infrastruttura buona nasca gratis e resti buona per inerzia.

In **Encodia**, quando parte un progetto WordPress nuovo di un certo livello, Radicle è spesso il punto da cui iniziamo a ragionare. Non per fede. Perché oggi è uno dei compromessi migliori tra pragmatismo WordPress e disciplina da applicazione moderna.

## Quando Roots ripaga

Roots ha senso quando il progetto ha una vita tecnica davanti, non quando deve solo esistere online.

L'adozione paga soprattutto in questi casi:

- **team di più di una persona**, perché Composer, Git e ambienti coerenti ripagano il costo iniziale appena non sei più da solo;
- **più ambienti**, perché sviluppo, _staging_, UAT e produzione devono smettere di essere parenti lontani;
- **CI/CD non opzionale**, con _deploy_ che passano da GitHub Actions e processi ripetibili;
- **codice _custom_ non banale**, come _custom post type_, integrazioni REST, CRM, ERP, blocchi Gutenberg _server-rendered_;
- **audit di sicurezza periodici**, dove `composer.lock` e `composer audit` danno tracciabilità reale;
- **indipendenza dai fornitori**, perché Trellis su Ubuntu e WP Packages indipendente riducono il rischio di restare incastrati.

La domanda vera, lato business, non è "Roots è moderno?". La domanda è: _quante volte toccheremo questo codice nei prossimi due anni?_

Se la risposta è "spesso", Roots può ripagarsi molte volte. Se la risposta è "quasi mai", probabilmente no.

## Quando è solo ingegneria inutile

Voglio essere chiaro: Roots può essere _overkill_.

Per un sito _brochure_ di cinque pagine che il cliente aggiorna due volte all'anno, un _hosting managed_ serio e un tema fatto bene sono più che sufficienti.

Per un cliente che vuole gestirsi tutto da solo, senza un partner tecnico, Composer e Git rischiano di diventare un costo cognitivo che nessuno assorbirà davvero. Il risultato peggiore è consegnare un progetto teoricamente elegante, ma che poi nessuno tocca più. In questi casi un Builder (l'ho scritto) è forse l'unica soluzione possibile.

Per un sito costruito attorno a plugin commerciali che non distribuiscono via Composer, il lavoro non finisce con un "non si può". Si può lavorare con repository privati, `composer/satis` o `wikimedia/composer-merge-plugin`. In **Encodia** usiamo Satis quando serve proprio per mettere sotto controllo anche dipendenze private e plugin commerciali: è una competenza pratica, non una nota a margine.

La parte da chiarire prima è un'altra: se una quota importante del valore del sito sta dentro plugin chiusi, il progetto richiede disciplina, budget e responsabilità adeguate. Roots resta una buona scelta, ma va governato da chi sa mettere ordine anche dove l'ecosistema WordPress non lo offre già pronto.

E poi ci sono i progetti piccoli, con budget piccolo e una sola persona coinvolta. In quei casi WordPress _vanilla_ su un hosting decente può essere la scelta giusta.

Non bisogna ingegnerizzare per sentirsi più intelligenti.

## Dove si vede la differenza

Un sito WordPress non costa quando lo pubblichi. Costa nei due anni dopo.

Costa quando un aggiornamento rompe una parte critica. Costa quando lo _staging_ non assomiglia alla produzione. Costa quando il fornitore precedente ha lavorato "direttamente online". Costa quando nessuno sa più quali plugin siano necessari e quali siano rimasti lì per paura di toccarli.

Roots non elimina questi problemi. Sarebbe una promessa da venditore.

Fa una cosa più utile: li rende gestibili.

E in un progetto WordPress serio, questa è quasi sempre la differenza tra un sito che cresce e un sito che, a un certo punto, tutti hanno paura di modificare.

Per le agenzie significa meno chiamate perché "il sito è giù", meno ore perse su ambienti incoerenti, meno dipendenza da quel singolo plugin che fa miracoli ma che nessuno sa più chi mantenga.

Per le aziende significa poter chiedere conto del processo, non solo del risultato visibile: come si aggiorna, come si torna indietro, chi ha responsabilità su cosa, quanto il sito dipende da scelte che nessuno sa più spiegare.

Per i colleghi significa fare WordPress senza sentirsi nel 2010.

Se un'azienda sta valutando un partner tecnologico per i propri asset web, e in quegli asset c'è WordPress, io farei tre domande prima ancora di guardare il preventivo:

1. _Come gestite dipendenze e aggiornamenti?_
2. _Quanto tempo serve per fare rollback dopo un deploy andato male?_
3. _Se domani un fornitore chiude, viene acquisito o cambia condizioni, quanto siete esposti?_

Sono domande che separano chi vende tranquillità a parole da chi ha davvero le mani nel motore.

## Domande frequenti su Roots e WordPress

### Roots sostituisce WordPress?

No. Roots non sostituisce WordPress: gli dà una struttura più adatta a progetti professionali, con Composer, Git, ambienti separati e deploy controllati.

### Quando ha senso usare Bedrock o Radicle?

Quando il sito ha una vita tecnica davanti: team, integrazioni, aggiornamenti frequenti, staging, CI/CD o responsabilità operative reali.

### WP Packages sostituisce WPackagist?

Può sostituirlo nei progetti WordPress gestiti con Composer. Il vantaggio è avere un repository più veloce, indipendente e con namespace più puliti.

### Roots è adatto a un sito costruito con un builder?

Dipende da quanto quel sito è diventato importante. Se il builder serve solo a pubblicare poche pagine che cambiano raramente, può bastare. Se il sito genera lead, integra servizi o richiede rilasci controllati, il problema non è il builder in sé: è capire quanto controllo hai davvero.

## Se vuoi parlarne sul serio

Se sei arrivato fin qui, probabilmente non stai cercando "un sito WordPress". Stai cercando un modo per non ritrovarti fra un anno con un asset importante che nessuno vuole toccare.

Dal _refactor_ di un'installazione esistente alla migrazione a Bedrock o Radicle, dal disegno di una pipeline CI/CD all'_audit_ tecnico di un fornitore che già gestisce il tuo sito, questo è il tipo di lavoro su cui posso entrare nel merito senza giri di parole.

Una premessa onesta: una consulenza di questo tipo paga sopra una certa soglia di complessità. Progetti con team interni, integrazioni, fatturato che passa dal sito, responsabilità operative reali.

Se la situazione è "WordPress _vanilla_ su un _hosting managed_, **va già abbastanza bene così**", questo articolo è probabilmente il consiglio più utile che potessi darti. **In tutti gli altri casi, scrivimi.**
