Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Platform Laravel Package

orchestra/platform

Orchestra Platform is a Laravel extension that provides a foundation for building admin panels and CMS-style applications, with ready-made components, user management, and extension support to speed up backend development.

View on GitHub
Deep Wiki
Context7

Getting Started

Confirm the framework baseline before you install anything. The only release evidence in this repository is v5.0.0, whose sole change is "Update support to Laravel Framework v7.0." That is a hard stop for most modern apps. Do the check in a scratch branch so a stray composer update can never touch your real lockfile:

composer show orchestra/platform --all     # head version, requires, suggests
composer require orchestra/platform --dry-run   # what the resolver actually wants

If the resolved head does not support your Laravel baseline, stop there. Do not downgrade the framework for a scaffolding layer.

Minimal install sequence (name the providers/config from the published list once you have run the dry run — auto-discovery is not guaranteed on this generation):

  1. composer require orchestra/platform
  2. Register the platform service provider(s) — on Laravel 7-era apps this means config/app.php providers[]; verify rather than assume.
  3. php artisan vendor:publish against the Orchestra tags, then php artisan migrate.
  4. Run the installer if present (php artisan orchestra:install) to seed the admin user, roles, and default ACL, or seed manually if it is broken on your PHP version.
  5. Log in at the published route prefix and confirm the dashboard renders.

Where to look first — the public docs are thin, so read in this order of information density:

Source What it tells you
vendor/orchestra/platform/ Ground truth. src/Providers/*, composer.json, resources/, migrations — this is the documentation
php artisan list filtered to the package The real command surface: install, extension activate/deactivate, resource generation
Published config/*.php The knobs you are allowed to turn; if it is not published, treat it as internal
routes/ inside the package Which routes exist, their middleware, and the ACL convention on each

First use case: prove all four load-bearing surfaces at once, not a hello-world. Build a "Support Tickets" admin screen that touches (a) a model + migration, (b) a CRUD resource in the admin nav, (c) an ACL role (support) that can view but not delete, and (d) one settings value (default assignee) read through the memory/settings API. If that flow is smooth, you have validated the package's actual value proposition in a day; if it fights you, you have learned the integration cost cheaply.

Implementation Patterns

Treat Orchestra as UI + routing + ACL, and keep domain logic in plain Laravel. This is the single most important day-to-day rule. The lock-in vector is business rules written inside extensions. Write services as normal Laravel classes with interfaces, then let the extension controller call them:

// app/Services/TicketService.php — portable
class TicketService {
    public function __construct(private TicketRepository $repo) {}
    public function escalate(Ticket $t, User $by): Ticket { /* rules live here */ return $t; }
}

// Orchestra-facing controller stays dumb
class TicketController {
    public function __construct(private TicketService $service) {}
    public function escalate(Ticket $t) {
        $this->service->escalate($t, auth()->user());
        return back();
    }
}

The exit test: delete vendor/orchestra and ask how much of app/ survives. Aim for "everything but controllers and menu registration."

Model the roadmap as extensions, one per capability. This is the reason to pick the package. An extension is a Composer package carrying Orchestra's manifest — copy the structure the generator produces rather than hand-writing the composer.json type/key. Working discipline:

  • One extension = one business capability, with its own migrations, routes, views, ACL entries, and menu items.
  • Extensions depend on your app/Services contracts, never on each other's internals.
  • Ship an MVP admin as three or four extensions, then let new operational needs arrive as installable modules rather than edits to the monolith. Version each extension on its own cadence.
  • Cross-extension communication goes through events and contracts, not direct class references.

Decide the ACL ownership boundary on day one. If you already use Gates/policies or Spatie, do not run two authorization models in parallel. Pick one as source of truth and have the other delegate. Centralize Orchestra checks behind one thin service so a later swap is one file:

class AccessService {
    public function canManageTickets(): bool { return /* Orchestra check, isolated here */ }
}

Settings and memory: typed wrapper with defaults, cache-aware writes. Memory/settings is a runtime store for values an admin edits — not a config file. Wrap it so a missing key never blows up a request and tests can stub it:

class TicketSettings {
    public function defaultAssignee(): ?int {
        return $this->memory->make('ticket')->get('default_assignee', null);
    }
}

Deploy-time values (queues, drivers, mail) stay in config/. Anything an admin edits at runtime belongs here.

Resource/CRUD scaffolding is a starting point, not an architecture. Let the generator emit the list/detail/form skeleton, then immediately take ownership: validation into FormRequests, filtering into query scopes, presentation into your own views. Generated CRUD left untouched becomes the thing that fights you at requirement three.

Registration checklist for every extension — each of these fails silently if forgotten:

  1. Service provider registered and booting under the right environment guard.
  2. Migrations published and run; confirm entries in the migrations table.
  3. Menu/nav item registered in the admin navigation.
  4. ACL permissions and role bindings created.
  5. Routes registered with the admin middleware stack — verify with php artisan route:list.

Keep adapters around every Orchestra surface you touch — navigation, ACL, settings, asset publishing. Under that convention, a fork-or-replace decision stays a UI rewrite rather than a re-architecture. Write it down before the pilot; retrofitting it rarely happens.

Gotchas and Tips

Version alignment is the hard stop, not the integration. Integration is roughly a day for a Laravel-fluent dev. But a documented head target of Laravel 7 is a past-end-of-security baseline. Verify head version on Packagist, release cadence over the last twelve months, maintainer count, and whether a branch exists for a newer Laravel major. Assume you own the upgrade path and budget for it explicitly.

Auto-discovery is not something to rely on. On this generation, providers frequently need explicit registration. If the admin 404s or routes are missing: php artisan route:list first, then config/app.php — in that order.

The vendor directory is the documentation. Zero dependents and near-zero stars means no blog posts, no Stack Overflow answers, no contractor pool. Build the habit of reading vendor/orchestra/*/src and the published migrations directly, and record what you learn in an ADR or README — you are writing the docs the project does not have. Budget extra time for every non-obvious question.

Extension activation is a state machine with a cache layer. Symptoms of stale state: a newly activated extension's migrations have not run, routes 404, or the menu item is missing. Debug order:

  1. php artisan cache:clear and php artisan config:clear — the extension registry is commonly cached.
  2. Re-run migrate (activation does not always imply migration).
  3. Dump the registered menu/route tables to see whether registration happened at all.

If you cannot see the state from an artisan command, write a two-line tinker script that dumps the registry — do not guess.

Published views and config are a fork in disguise. Once you edit a published view or config file, upgrading means diffing your change against the new defaults. Keep a patches/ note per published file with the reason, and prefer overriding through your own view namespace or a child layout where possible.

Asset publishing breaks quietly when the public path or a source map changes. If CSS/JS vanishes after a deploy, check the publish manifest and public-disk permissions before touching any code.

Two authorization models will bite you. If Orchestra's ACL coexists with Laravel Gates or Spatie, write one integration test per role that asserts both systems agree on a sensitive action. Privilege bugs are cheap in tests and expensive in an audit.

Debugging a blank admin page. Order of operations: storage/logs/laravel.log → APP_DEBUG=true → php artisan view:clear → asset publish state → provider boot order. Boot order is the most common root cause and the least obvious; if a dependency provider boots after its consumer, registrations silently no-op.

Testing notes. Orchestra's bootstrapping adds provider overhead — keep a base test case that boots the platform once. Test extensions against the service layer (fast, portable) and keep a small number of end-to-end tests through the admin HTTP stack with real roles; those are the ones that catch ACL regressions.

When to walk away mid-pilot. If the confirmed head does not support your Laravel baseline, or your back office needs a fundamentally nonstandard permission model or heavy bespoke workflows such that you would rewrite the scaffolding anyway — stop. The cost of stopping at day one is a day; the cost of stopping after a quarter is a quarter. Compare honestly against Filament, Backpack, or Nova if the extension system turns out not to be load-bearing for your roadmap.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource