Adventures upgrading to Tailwind 4 and Filament 4

Upgrading Laravel

Here is my documentation around upgrading many (!) projects from Filament 3 to 4. Actually, in an ideal world, I would have liked to just upgrade Filament. However, there is this additional requirement of upgrading Tailwind, meaning I have to do Vite work too.

Let's get started. This would be typical in one of these projects:

art --version
Laravel Framework 12.28.1
lang-bash

For projects that don't have Laravel 12 on already, I just refer to the upgrade guide.

cat package.json

{
    "private": true,
    "type": "module",
    "scripts": {
        "build": "vite build",
        "dev": "vite"
    },
    "devDependencies": {
        "autoprefixer": "^10.4.20",
        "axios": "^1.7.4",
        "concurrently": "^9.0.1",
        "laravel-echo": "^1.17.1",
        "laravel-vite-plugin": "^1.0",
        "postcss": "^8.4.47",
        "pusher-js": "^8.4.0-rc2",
        "tailwindcss": "^3.4.13",
        "vite": "^5.0"
    }
}
lang-json

`package.json` is the more interesting one, because here we can we can see very outdated versions of both `vite` and `laravel-vite-plugin`. So let's do that first by installing the latest files as dev dependencies.

npm install -D vite@latest
npm install -D laravel-vite-plugin@latest
lang-bash

If you do it the other way around, you'll get a warning about the Laravel package being outdated.

After installing the latest versions of those two key components things look better:

"laravel-vite-plugin": "^2.0.1",
"vite": "^7.1.10"
lang-json

Next, evaluate what custom CSS you're using. A lot of this will be migrated.

The problem I found is with the Tailwind updater is that it fails miserably on `Migrating Templates` step. Basically, it just hangs. What seems to be going on here is when you run the Tailwind upgrade command, it scans your entire project including `/public/**` and then tries to work it's magic there. However, in Laravel projects, you'll have a bunch of existing assets that throws it off.

Here is an example:

image.png 6.96 KB
Word on the street is "upgrade Filament first", so let's do that first by installing the Filament upgrade plugin. The instructions below were taken from the official Filament upgrade guide here: https://filamentphp.com/docs/4.x/upgrade-guide.

composer require filament/upgrade:"^4.0" -W --dev
lang-bash

You can't upgrade Filament if all your plugins are not compatible. I generally abort upgrades if this is the case and I know a specific plugin is really needed. To find out what's not upgradable, you can look on the Filament website or just run the upgrade script, it will warn you about incompatibilities. On some of my projects that means I have to remove at least these two:

"saade/filament-fullcalendar": "^3.0",
"saade/filament-laravel-log": "^3.0",
lang-json

Saade's Filament Log will be in `AdminPanelProvider.php`, so be sure to remove that too.

Here is the actual upgrade command:

vendor/bin/filament-v4
lang-bash

Run *all* the commands it spits out. For example, you might see something like this:

composer require filament/filament:"^4.0" -W --no-update
composer require parfaitementweb/filament-country-field:"^2.0" -W --no-update
composer require stechstudio/filament-impersonate:"^4.0" -W --no-update
composer require tapp/filament-auditing:"^4.0" -W --no-update
composer require valentin-morice/filament-json-column:"dev-dev" -W --no-update
composer require ysfkaya/filament-phone-input:"^4.0" -W --no-update
lang-bash

Then:

composer update
lang-bash

Next, we go big and update all files to new locations:

art filament:upgrade-directory-structure-to-v4
lang-bash

Then we can remove the upgrade script:

composer remove filament/upgrade --dev

If you're using version control, I also recommend you run this (note force - be sure to have version control):

art vendor:publish --tag=filament-config --force
lang-bash

Next, maybe some heavy lifting finding breaking changes and if you've used custom themes. In that case, follow the rest of the guide here: https://filamentphp.com/docs/4.x/upgrade-guide#breaking-changes-that-must-be-handled-manually

Upgrading Tailwind 4

Since upgrading Tailwind is a mission on Laravel projects with things like Filament and Horizon, I've split the Tailwind information into two sections. I would generally recommend you first check the official guide, maybe out of the box is just works for you: https://tailwindcss.com/docs/upgrade-guide

Here are typical problems:

  • The upgrade trashes all your files. I've seen it restore them after a while, but looking at 70 then 230 files just disappear (blank content), is very nerve wrecking.
  • The upgrade chokes on Migrating templates.
  • The upgrade never completes on Migrating templates.
  • │ ↳ Could not load the configuration file: Cannot find module './vendor/filament/support/tailwind.config.preset' 

The best advice I found was researching the choking and an article that recommended temporary moving everything out of /public before the upgrade, and back again after the upgrade. 

Instructions for upgrading:

npx @tailwindcss/upgrade
npm install @tailwindcss/vite
npm uninstall postcss
lang-bash

The next part of the document is failed abort about upgrading Tailwind. For some time I though I could get away or delay Tailwind CSS 4 upgrades, but it turns out I use Reverb extensively and you can't get working properly after all these "upgrades" unless you also upgrade Tailwind.

For example, I tried installing Broadcasting on an up to date system and I got:

app git:(main) ✗ art install:broadcasting
   ERROR  The 'broadcasting' configuration file already exists.  

 ┌ Which broadcasting driver would you like to use? ────────────┐
 │ Laravel Reverb                                               │
 └──────────────────────────────────────────────────────────────┘

 ┌ Would you like to install and build the Node dependencies required for broadcasting? ┐
 │ Yes                                                                                  │
 └──────────────────────────────────────────────────────────────────────────────────────┘

   INFO  Installing and building Node dependencies.  

up to date, audited 230 packages in 1s

48 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

> build
> vite build

vite v7.1.7 building for production...
...
✗ Build failed in 497ms
error during build:
[vite:css] [postcss] Cannot find module './vendor/filament/support/tailwind.config.preset'
Require stack:
- /Volumes/nvme/Code/app/tailwind.config.js
file: /Volumes/nvme/Code/app/resources/css/app.css:undefined:NaN
    at Function._resolveFilename (node:internal/modules/cjs/loader:1383:15)
    at Function.resolve (node:internal/modules/helpers:157:19)
    at _resolve (/Volumes/nvme/Code/app/node_modules/jiti/dist/jiti.js:1:241814)
    at jiti (/Volumes/nvme/Code/app/node_modules/jiti/dist/jiti.js:1:244531)
    at /Volumes/nvme/Code/app/tailwind.config.js:4:29
    at evalModule (/Volumes/nvme/Code/app/node_modules/jiti/dist/jiti.js:1:247313)
    at jiti (/Volumes/nvme/Code/app/node_modules/jiti/dist/jiti.js:1:245241)
    at /Volumes/nvme/Code/app/node_modules/tailwindcss/lib/lib/load-config.js:56:30
    at loadConfig (/Volumes/nvme/Code/app/node_modules/tailwindcss/lib/lib/load-config.js:58:6)
    at getTailwindConfig (/Volumes/nvme/Code/app/node_modules/tailwindcss/lib/lib/setupTrackingContext.js:71:116)
   WARN  Node dependency installation failed. Please run the following commands manually: npm install --save-dev laravel-echo pusher-js && npm run build.  
lang-bash

Upgrading Tailwind

As mentioned, the biggest problem I found with Tailwind upgrades is it hangs because it traverses /public and then tries to do stuff that bombs it out. Make sure you have version control and time on your hands!

Let's try this now on a production project now from https://tailwindcss.com/docs/upgrade-guide :

First commit latest changes otherwise Tailwind upgrade will not work.

npx @tailwindcss/upgrade

Same preset issue. Let's remove that from tailwind.config.js by commenting it out at two places

O gosh, I'm using Flowbite in this project too!

↳ Could not load the configuration file: Cannot use 'in' operator to search for '__isOptionsFunction' in 
│   flowbite/plugin 

Let's remove that for now.

On the next npx upgrade attempt, the system takes very long on sections, and there are really scary moments where it appears to trash you entire source code with no files. This especially happens on this step:

Migrating templates… 

It's really scary but don't panic. Just leave it for a while, your source code will come back. I've had to wait up to...

Scrap that, I waited longer than 5 minutes and all my code was trashed. I reverted.

I selectively took files out of public, but Tailwind still choked on the Migrating templates steps.

Upgrade aborted.