# Upgrading Acorn to the Latest Version

## Upgrading to v6.x from v5.x

Acorn v6 includes Laravel v13 components, whereas Acorn v5 includes Laravel v12 components.

### Upgrading dependencies

Acorn v6 requires PHP >= 8.3.

Update the `roots/acorn` dependency in your `composer.json` file to `^6.0`:

```shell
$ composer require roots/acorn ^6.0 -W
```

The `-W` flag is required to upgrade the included Laravel dependencies.

::: warning
If any packages/dependencies have conflicts while updating, try removing and then re-requiring them after Acorn is bumped to 6.x.
:::

### Breaking changes

#### Cache, session, and Redis prefix separators

The default prefix/cookie separators have changed from underscores to hyphens to match Laravel 13 defaults. This means:

- **Cache prefix**: `laravel_cache_` → `laravel-cache-`
- **Session cookie**: `laravel_session` → `laravel-session`
- **Redis prefix**: `laravel_database_` → `laravel-database-`

This will **invalidate existing caches and log out all sessions** unless you have explicitly set these values via environment variables (`CACHE_PREFIX`, `SESSION_COOKIE`, `REDIS_PREFIX`).

To preserve existing behavior, add these to your `.env`:

```plaintext
CACHE_PREFIX=your_app_name_cache_
SESSION_COOKIE=your_app_name_session
REDIS_PREFIX=your_app_name_database_
```

#### Mail configuration

The SMTP `encryption` key has been replaced with `scheme`:

```diff
  'smtp' => [
      'transport' => 'smtp',
-     'encryption' => env('MAIL_ENCRYPTION', 'tls'),
+     'scheme' => env('MAIL_SCHEME'),
  ],
```

If you are using the `MAIL_ENCRYPTION` environment variable, rename it to `MAIL_SCHEME`.

If you use [`roots/acorn-mail`](https://github.com/roots/acorn-mail), bump it to `^2.0` — earlier versions read the removed `encryption` key and will silently ignore `MAIL_SCHEME`:

```shell
$ composer require roots/acorn-mail ^2.0
```

#### Logging configuration

The stderr channel's `with` key has been renamed to `handler_with`:

```diff
  'stderr' => [
      'driver' => 'monolog',
      'handler' => StreamHandler::class,
-     'with' => [
+     'handler_with' => [
          'stream' => 'php://stderr',
      ],
  ],
```

### Config changes

If you have published Acorn's configs, you should review and update them based on the latest versions in the [Acorn repo](https://github.com/roots/acorn/tree/main/config). Notable changes include:

- **cache.php**: New `serializable_classes` option
- **session.php**: New `serialization` option
- **database.php**: New Redis retry/backoff keys, SQLite `transaction_mode`, SSL CA guard updated for PHP 8.5
- **mail.php**: New `resend` and `roundrobin` mailers, `retry_after` on failover, `markdown` section removed
- **services.php**: Postmark and Resend env variable names updated
- **All configs**: `(string)` casts added to `env()` calls per Laravel 13 conventions

## Upgrading to v5.x from v4.x

Acorn v5 includes Laravel v12 components, whereas Acorn v4 includes Laravel v10 components.

### Upgrading dependencies

Acorn v5 requires PHP >= 8.2.

Update the `roots/acorn` dependency in your `composer.json` file to `^5.0`:

```shell
$ composer require roots/acorn ^5.0 -W
```

The `-W` flag is required to upgrade the included Laravel dependencies.

::: warning
If any packages/dependencies have conflicts while updating, try removing and then re-requiring them after Acorn is bumped to 5.x.
:::

### Breaking changes

The most significant change in v5 is how Acorn is booted. The `bootloader()` helper has been deprecated in favor of using `Application::configure()`. This change aligns Acorn with Laravel 11's new application configuration system, providing a more fluent and powerful way to configure your application.

You'll need to import the Application class at the top of your file:

```php
use Roots\Acorn\Application;
```

Then update your bootstrapping code:

```diff
- add_action('after_setup_theme', fn () => \Roots\bootloader()->boot(), 0);
+ add_action('after_setup_theme', function () {
+     Application::configure()
+         ->withProviders([
+             App\Providers\ThemeServiceProvider::class,
+         ])
+         ->boot();
+ }, 0);
```

If you have previously registered service providers through either `composer.json` (`extra.acorn.providers`) or `config/app.php`, you'll need to migrate these to the new configuration method. All providers should now be registered using `withProviders()` when configuring the application. Remove any provider configurations from your composer.json and config files, and instead register them directly in your bootstrapping code:

```php
Application::configure()
    ->withProviders([
        App\Providers\ThemeServiceProvider::class,
        App\Providers\ExampleServiceProvider::class,
    ])
    ->boot();
```

### Routing

Acorn v5 introduces support for Laravel’s routing features within WordPress. If you previously used Livewire, you may encounter an error such as `Route [livewire.update] not defined`, or experience other routing-related issues.

To resolve this, and to enable routing, ensure your application is properly configured by adding the `withRouting` method:

```diff
Application::configure()
    ->withProviders([
        App\Providers\ThemeServiceProvider::class,
    ])
+   ->withRouting(wordpress: true)
    ->boot();
```

### Config changes

If you have published Acorn's configs, you should review and update them based on the latest versions in the [Acorn repo](https://github.com/roots/acorn/tree/main/config).

## Upgrading to v4.x from v3.x

Acorn v4 includes Laravel v10 components, whereas Acorn v3 includes Laravel v9 components.

### Upgrading dependencies

Acorn v4 requires PHP >= 8.1.

Update the `roots/acorn` dependency in your `composer.json` file to `^4.0`:

```shell
$ composer require roots/acorn ^4.0 -W
```

The `-W` flag is required to upgrade the included Laravel dependencies.

::: warning
If any packages/dependencies have conflicts while updating, try removing and then re-requiring them after Acorn is bumped to 4.x.
:::

### Config changes

If you previously published Acorn's config(s), you will need to update them based on the configs in the [Acorn repo](https://github.com/roots/acorn/tree/main/config) ([history](https://github.com/roots/acorn/commits/main/config?since=2023-11-01&until=2024-01-31)). You mainly need the [new provider changes](https://github.com/roots/acorn/blob/v4.0.0/config/app.php#L160-L169) if you published `config/app.php`.

```diff
+ use Roots\Acorn\ServiceProvider;

-    'timezone' => get_option('timezone_string', 'UTC'),
+    'timezone' => get_option('timezone_string') ?: 'UTC',

-    'providers' => [
+    'providers' => ServiceProvider::defaultProviders()->merge([
-
-        /*
-         * Framework Service Providers...
-         */
-        Illuminate\Auth\AuthServiceProvider::class,
-        Illuminate\Broadcasting\BroadcastServiceProvider::class,
-        Illuminate\Bus\BusServiceProvider::class,
-        // ...
-        Roots\Acorn\Providers\AcornServiceProvider::class,
-        Roots\Acorn\Providers\RouteServiceProvider::class,
-        Roots\Acorn\View\ViewServiceProvider::class,


         /*
          * Package Service Providers...
          */

         /*
          * Application Service Providers...
          */
         // App\Providers\ThemeServiceProvider::class,

-    ],
+    ])->toArray(),
```

### Breaking changes

The breaking changes this time are minimal and should not impact most users.

Service providers should now extend Illuminate:

```diff
- use Roots\Acorn\ServiceProvider;
+ use Illuminate\Support\ServiceProvider;
```

View Composer `Arrayable` trait uses property [`Composer::$except`](https://github.com/roots/acorn/blob/70d179955cddc61f0c6101717af2fdf88cf38831/src/Roots/Acorn/View/Composer.php#L35-L54) instead of `Arrayable::$ignore`.

```diff
 class Alert extends Composer
 {
     use Arrayable;

-    $ignore = ['token'];
+    $except = ['token'];
 }
```

Asset Contract adds [`relativePath()` method](https://github.com/roots/acorn/blob/70d179955cddc61f0c6101717af2fdf88cf38831/src/Roots/Acorn/Assets/Contracts/Asset.php#L38). So if you're implementing this contract, you'll need to update it. (Most users will not be impacted by this.)

```diff
 class MyAsset implements Asset
 {
+    relativePath(string $base_path): string
+    {
+        // ...
+    }
 }
```

## Upgrading to v3.x from v2.x

Acorn v3 includes Laravel v9 components, whereas Acorn v2 includes Laravel v8 components.

### Upgrading dependencies

Acorn v3 requires PHP >= 8.0.2.

Update the `roots/acorn` dependency in your `composer.json` file to `^3.0`:

```shell
$ composer require roots/acorn ^3.0 -W
```

The `-W` flag is required to upgrade the included Laravel dependencies.

### Theme/application

Acorn v2 is typically booted in your WordPress theme's `functions.php` file. Look for the line that includes `\Roots\bootloader()`, and replace it with `\Roots\bootloader()->boot()`.

```diff
-\Roots\bootloader();
+\Roots\bootloader()->boot();
```

We highly recommend removing the exception from bootloader to prevent service providers from silently skipping on local dev, a change that was introduced in Acorn v3.1.0 ([PR #266](https://github.com/roots/acorn/pull/266)) and Sage v10.5.1 ([PR #3121](https://github.com/roots/sage/pull/3121/files)). Replace the original bootloader method:

```php
try {
    \Roots\bootloader()->boot();
} catch (Throwable $e) {
    wp_die('You need to install Acorn to use this theme.'),
    ...
}
```

With the new one:

```php
if (! function_exists('\Roots\bootloader')) {
    wp_die(
        __('You need to install Acorn to use this theme.', 'sage'),
        '',
        [
            'link_url' => 'https://roots.io/acorn/docs/installation/',
            'link_text' => __('Acorn Docs: Installation', 'sage'),
        ]
    );
}

add_action('after_setup_theme', fn () => \Roots\bootloader()->boot(), 0);
```

You can also remove the theme support added for Sage if you are working on a Sage-based WordPress theme:

```diff
-add_theme_support('sage');
```

#### Target class [sage.view] does not exist

Some setups may require changes if you run into the following error:

```plaintext
Target class [sage.view] does not exist
```

In this case, edit the `ThemeServiceProvider` and make sure it extends `SageServiceProvider` and has `parent::` calls to `register()` and `boot()` if they are present:

```diff
# app/Providers/ThemeServiceProvider.php

namespace App\Providers;

-use Roots\Acorn\ServiceProvider;
+use Roots\Acorn\Sage\SageServiceProvider;

-class ThemeServiceProvider extends ServiceProvider
+class ThemeServiceProvider extends SageServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
-        //
+        parent::register();
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
-        //
+        parent::boot();
    }
}
```

After doing so, you may need to delete [Acorn's application cache directory](https://roots.io/acorn/docs/directory-structure/). By default, this is located in `[wp-content|app]/cache/acorn/`.

Reference the [Acorn v3 upgrade pull request on the Sage repo](https://github.com/roots/sage/pull/3097) to see a full diff.

#### Target class [assets.manifest] does not exist

Some setups may require changes if you run into the following error:

```plaintext
Target class [assets.manifest] does not exist
```

This error can be fixed by copying over the latest changes to the [`config/app.php` file](https://github.com/roots/acorn/blob/67cce76e6ca13e28acaced3333d77e2f779b07a3/config/app.php) from Acorn.