Matriks Kompatibilitas
Dokumen ini menjelaskan versi yang benar-benar diuji oleh package ini, versi yang sekadar masih dapat ditoleransi, dan versi yang tidak akan bekerja. Setiap versi pada kolom Supported merupakan versi yang benar-benar dijalankan CI pada setiap push — lihat .github/workflows/tests.yml — sehingga tabel ini menggambarkan kondisi build yang nyata, bukan sekadar target atau niat dukungan.
Periksa Aplikasi Anda Sendiri
composer why chocoalano/panel
composer show laravel/framework inertiajs/inertia-laravel laravel/fortify | grep -E 'name|versions'
node -v
npm ls vue tailwindcss vite @inertiajs/vue3 --depth=02
3
4
Jika salah satu hasil di atas berada di bawah versi minimum pada tabel berikut, error yang muncul biasanya bukan pesan "versi tidak kompatibel". Anda justru akan melihat build error tentang module specifier atau HTTP 500 karena method yang tidak tersedia — error tersebut benar, tetapi menunjuk ke gejala yang salah.
Backend
| Didukung | Catatan | |
|---|---|---|
| PHP | 8.2, 8.3, 8.4 | PHP 8.2 didukung melalui Laravel 12, yaitu Laravel terbaru yang masih dapat berjalan di PHP 8.2. |
| Laravel | 12.x, 13.x | Lihat Mengapa Bukan Laravel 11. |
| Testbench | 10.x (L12), 11.x (L13) | Hanya relevan untuk test suite repository package ini sendiri. |
| Inertia (server) | inertiajs/inertia-laravel 3.x | Versi 2.x tidak didukung. |
| Fortify | 1.37.2+ | Security Settings dan second factor melalui kode email sama-sama dibangun di atas Fortify. |
| Database | MySQL, PostgreSQL, SQLite, MariaDB | Tidak ada implementasi yang spesifik ke database engine tertentu. Suite berjalan di SQLite; query menggunakan Eloquent biasa. |
Apa yang Benar-Benar Dijalankan CI
matrix:
php: ['8.2', '8.3', '8.4']
laravel: ['12.*', '13.*']
stability: [prefer-lowest, prefer-stable]
exclude:
- php: '8.2'
laravel: '13.*'2
3
4
5
6
7
Totalnya sepuluh job: hasil silang PHP × Laravel × prefer-lowest/prefer-stable, dikurangi kombinasi yang memang tidak tersedia. Pengujian prefer-lowest membuktikan batas bawah dari setiap dependency range yang dideklarasikan. Jika sebuah dependency hanya bekerja pada versi terbarunya, berarti constraint package tersebut salah; prefer-lowest dirancang untuk menemukan masalah seperti ini.
Kombinasi PHP 8.2 × Laravel 13 dikeluarkan karena Laravel 13 membutuhkan PHP 8.3. Pengguna PHP 8.2 menggunakan Laravel 12, dan kombinasi tersebut benar-benar dijalankan sebagai job CI, bukan sekadar diasumsikan kompatibel.
Static analysis dijalankan dua kali: PHP 8.2 / Laravel 12 dan PHP 8.4 / Laravel 13. Kedua ujung range ini benar-benar memiliki API yang berbeda — misalnya Password::toPasswordRulesString() hanya ada pada Laravel 13 — sehingga hanya menganalisis satu ujung dapat melewatkan pemanggilan yang rusak di ujung lainnya.
Mengapa Bukan Laravel 11
Ada dua alasan, dan alasan kedua bersifat menentukan.
Masa dukungan security-nya sudah berakhir. Laravel 11 dirilis pada Maret 2024; berdasarkan kebijakan dukungan Laravel, security fixes untuk versi tersebut berakhir pada Maret 2026.
Composer tidak akan menginstalnya. Seluruh release Laravel 11.x ditandai oleh security advisory yang belum ditambal. composer update dengan constraint ^11.x tidak dapat menyelesaikan dependency graph — Composer menampilkan advisory ID lalu berhenti. Sebuah package tidak dapat mengklaim mendukung versi yang bahkan tidak dapat dipasang oleh CI-nya sendiri.
Dampaknya lebih kecil daripada yang terlihat: aplikasi yang masih menggunakan PHP 8.2 tetap didukung penuh. Yang tidak didukung secara spesifik adalah Laravel 11, bukan PHP versi lama secara umum.
Frontend
Component yang dipublish adalah Vue 3 SFC dengan Tailwind 4 dan dibuild oleh Vite milik aplikasi. Range dependency berasal dari package.json, yang menjadi satu-satunya sumber kebenaran: php artisan panel:install membaca file yang sama untuk memberi tahu aplikasi dependency apa yang harus dipasang, sehingga dokumentasi dan installer tidak dapat berbeda daftar.
| Didukung | Catatan | |
|---|---|---|
| Node | 20.19+, 22, 24 | Ketiganya ada di CI. Node 20.19 adalah batas minimum Vite 7 dan nilai yang dideklarasikan oleh engines.node. |
| Vue | 3.5+ | Menggunakan defineModel, useTemplateRef. |
| Inertia (client) | @inertiajs/vue3 3.x | Dipasangkan dengan inertia-laravel 3.x. |
| Vite | 7.x | Menggunakan versi Vite dari build milik aplikasi. |
| Tailwind | 4.1+ | CSS-first: theme, variant, dan @source semuanya berada di resources/css/panda-panel.css. Tailwind 3 tidak memiliki @theme dan tidak dapat mengompilasinya. |
| TypeScript | 5.7+ | Hanya relevan jika aplikasi menjalankan type checking. Component adalah .vue dengan lang="ts". |
| reka-ui | 2.x | Digunakan di balik setiap primitive components/ui/*. |
| TanStack Table | @tanstack/vue-table 9.x | Digunakan untuk column model, visibility, dan row selection. Sorting, filtering, serta pagination tetap server-side. |
CI kedua menginstal versi tertinggi yang masih masuk ke setiap range menggunakan npm install --no-package-lock, lalu melakukan build ulang. Job ini diperbolehkan gagal: jika upstream minor release merusak build, itu adalah informasi penting tetapi bukan alasan untuk memblokir pull request yang tidak berkaitan. npm ci terhadap lockfile yang sudah dikomit tidak dapat menangkap kasus ini karena lockfile mengunci hasil resolusi dependency dari waktu sebelumnya.
Asumsi Starter Kit
Component yang dipublish mengimpor beberapa module yang tidak dikirim oleh package. Module tersebut adalah milik aplikasi dan terbagi menjadi dua jenis:
- Generated —
@/routes/*dan@/actions/*berasal dari Wayfinder dan dibuat berdasarkan route table aplikasi Anda sendiri. Menyertakan salinannya di package berarti mengirim snapshot route milik aplikasi lain. - Component starter kit —
@/components/UserMenuContent,@/composables/useTwoFactorAuth, dan module sejenis. Di sinilah project menyimpan account link dan two-factor flow miliknya sendiri; jika package mengirim salinan sendiri, package berisiko menimpa file yang sudah dimiliki dan dimodifikasi oleh setiap starter kit/project.
panel:install memeriksa semuanya dan menyebutkan nama module yang belum tersedia. Daftar lengkapnya ada di Frontend requirements.
Dalam praktiknya: aplikasi Laravel Vue starter kit dapat bekerja langsung; aplikasi selain itu harus menyediakan module-module tersebut terlebih dahulu.
Bagian Starter Kit yang Diambil Alih Panel
Dua alamat starter kit berhenti menjadi screen mandiri, tetapi URL-nya tetap ada:
| Yang terjadi | Cara mempertahankan milik Anda | |
|---|---|---|
/dashboard | User yang sudah sign-in diarahkan ke Panel pertama yang dapat diakses. Route, nama route, dan pages/Dashboard.vue tidak diubah. | home_redirect.enabled => false |
/settings/* | Package tidak melakukan apa pun. Example application mengarahkannya ke Settings Page milik Panel — lihat SettingsRedirectController pada examples/. | Jangan menyalin controller tersebut |
Semua file yang dipublish package masuk ke path yang didefinisikan oleh PandaPanel\Support\Installer\PublishedAssets::map(). Tidak ada bagian aplikasi lain yang dibaca, diedit, atau ditimpa.
Yang Sengaja Tidak Didukung
| Alasan | |
|---|---|
| Inertia (server) 2.x | Form Panel menggunakan component <Form> dari Inertia 3 dan event router flash. Keduanya tidak tersedia pada 2.x dan tidak ada shim yang dapat menggantikannya secara benar. |
| Tailwind 3 | resources/css/panda-panel.css merupakan stylesheet Tailwind 4 — menggunakan @theme, @custom-variant, @source. Tailwind 3 tidak memahami directive tersebut. |
| React, Svelte | Component frontend dibuat sebagai Vue SFC. Bagian server — resources, tables, forms, actions, policies — bersifat framework-agnostic dan diserialisasikan menjadi array biasa, sehingga frontend lain secara teori memungkinkan; namun implementasinya tidak tersedia dan tidak direncanakan. |
| Aplikasi Blade-only | Setiap screen Panel adalah Inertia response. Tanpa middleware dan root view Inertia, URL Panel pertama menghasilkan HTTP 500. |
| Laravel 11 dan lebih lama | Sudah di luar masa security support dan tidak dapat di-resolve Composer — lihat Mengapa Bukan Laravel 11. |
Octane, Queue, dan Long-Lived Process
Tidak ada request state yang disimpan package dalam static property. Current Panel, current parent record, dan current tenant semuanya berada di PandaPanel\Support\PanelContext, yang merupakan scoped container binding. State tersebut direset di awal setiap request oleh PandaPanel\Http\Middleware\ResetPanelContext — middleware ini diregistrasikan pada seluruh group web agar tetap berjalan bahkan untuk request yang tidak pernah masuk ke Panel.
Queued work berada di luar request dan karena itu di luar semua context tersebut. Pekerjaan yang tenant-scoped harus memasuki tenant secara eksplisit:
use PandaPanel\Tenancy\Tenancy;
Tenancy::for($tenant, fn () => InvoiceResource::query()->count());2
3
Resource yang memiliki tenant scope tetapi dipanggil di luar tenant akan melempar exception, bukan menjalankan query tanpa scope. Ini disengaja: query tanpa scope dapat mengembalikan record dari seluruh tenant dan terlihat seolah-olah bekerja normal, padahal merupakan kebocoran data.
Menjaga Published Frontend Tetap Terbaru
Vue component Panel dipublish ke aplikasi, sehingga package update tidak otomatis memperbaruinya. Ini merupakan trade-off yang disengaja — component registry menggunakan build-time import.meta.glob allowlist terhadap tree aplikasi sendiri — tetapi jika dibiarkan, frontend akan tertinggal semakin jauh setiap release.
composer update chocoalano/panel
php artisan panel:assets # what is behind, what you changed, what conflicts
php artisan panel:assets --update # write only the files you have never touched
npm run build2
3
4
| Di disk | Di package | Dilaporkan sebagai | Ditulis oleh --update |
|---|---|---|---|
| belum pernah dipublish | tersedia | new | ya |
| = manifest | ≠ manifest | out of date | ya |
| ≠ manifest | = manifest | yours | tidak |
| ≠ manifest | ≠ manifest | CONFLICT | tidak pernah |
| tidak ada | tersedia | deleted by you | tidak |
| ada di manifest | tidak lagi dikirim | no longer shipped | tidak |
Mekanisme ini menggunakan .panel-assets.json, yang dibuat saat instalasi dan menyimpan hash setiap file pada saat file tersebut dipublish. Nilai ketiga ini yang memungkinkan sistem membedakan file yang tertinggal versi dari file yang memang diedit oleh aplikasi — perbedaan yang tidak mungkin diketahui oleh vendor:publish, karena keduanya sama-sama terlihat sebagai "berbeda dari salinan package". Commit manifest tersebut; fungsinya setara dengan composer.lock yang mencatat apa yang diinstal.
File yang berubah di kedua sisi dilaporkan berdasarkan path dan tidak pernah ditulis otomatis. Ini adalah satu kasus yang memang tidak seharusnya diselesaikan tool dengan tebakan.
Catatan
prefer-lowestmerupakan bagian dari contract compatibility. Jika aplikasi Anda mem-pin dependency di bawah batas bawah range pada dokumen ini, kombinasi tersebut tidak diuji — termasuk oleh CI package ini sendiri.- Frontend range tidak dikirim sebagai lockfile.
package-lock.json, Vite config, tsconfig, dan lint config semuanyaexport-ignorepada.gitattributes, sehinggacomposer requiretidak membawanya.package.jsonsengaja tidak di-ignore:panel:installmembaca daftar dependency darivendor/untuk memberi tahu aplikasi package apa yang harus dipasang. Jika file itu di-export-ignore, installer akan menganggap daftar dependency kosong. Aplikasi Anda menginstal berdasarkan range, bukan lockfile package. - Temuan
panel:assetsbukan kegagalan command. Command tetap exit0walaupun ada conflict. Menggagalkan deployment hanya karena sebuah file sengaja diedit aplikasi merupakan behavior yang salah.
Lihat Juga
- Requirements — constraint dan alasan setiap dependency dibutuhkan
- Installation — instalasi pada aplikasi yang memenuhi requirement
- Frontend requirements — npm package, host module, dan build
- Upgrading — perubahan antar-versi dan perbaikan terkecilnya
- Asset manifest — detail three-way comparison
- Deployment: production checklist