arkecosystem/foundation
Foundation is a foundational Laravel/PHP package for the Ark Ecosystem, providing shared base classes, configuration, and common utilities that other Ark packages build on. It helps bootstrap consistent structure and reduce boilerplate across projects.
What this package is. arkecosystem/foundation is a starter kit / scaffolding package: it ships Blade layouts, TailwindCSS presets, and Livewire components you publish into an app to get a working UI shell quickly. It is not a domain library — there is no meaningful runtime API to call. Treat it as a template you copy from, not a framework you build on top of.
Before you install, check compatibility. With 1 star, 0 dependents, and a single maintainer history, the package is effectively unmaintained. Two minutes of due diligence saves hours:
composer show -a arkecosystem/foundation
# read the require block: laravel/framework, livewire/livewire, tailwind version constraints
If it pins livewire/livewire:^2.0 and you're on Livewire 3, or it expects Laravel Mix while you're on Vite, stop here — you're better off copying the views out of the repo by hand.
Install and publish.
composer require arkecosystem/foundation
php artisan vendor:publish --provider="ArkEcosystem\Foundation\FoundationServiceProvider"
Run php artisan vendor:publish with no arguments first to see exactly which tag groups the package registers (foundation-config, foundation-views, foundation-assets, or similar). Do not blind-publish with --force on a project that already has resources/views/layouts/app.blade.php.
Where to look first, in this order:
vendor/arkecosystem/foundation/composer.json — the extra.laravel.providers entry tells you the real service provider FQCN; the require block tells you whether it's viable.vendor/arkecosystem/foundation/src/ — usually a service provider, maybe a View/Components directory. If it's tiny, the package is pure stubs.vendor/arkecosystem/foundation/resources/views/ — this is the actual product. Layouts, Blade components, Livewire views.vendor/arkecosystem/foundation/tailwind.config.js (or preset.js) — the design tokens and content globs you'll need to merge into your own config.First use case. The one workflow this package genuinely earns its keep on: standing up an internal admin/dashboard shell in an afternoon. Publish the views, point a route at the dashboard view, run npm run dev, and you have a working Tailwind + Livewire layout. Then delete the composer dependency and keep the published files as first-party code.
Pattern 1 — Scaffold once, then own the code. This is the correct default. Publish views and assets, commit them, then:
composer remove arkecosystem/foundation
You lose nothing (there's no runtime logic worth keeping), and you stop inheriting an unmaintained dependency. Your resources/views/layouts/app.blade.php becomes a normal file you can refactor freely.
Pattern 2 — Use the repo as a source of truth, not a dependency. Clone ArkEcosystem/laravel-foundation, diff its resources/views against your app, and cherry-pick. Sidesteps every version-constraint and autoload problem entirely, and gives you the commit history for context on why a component looks the way it does.
Pattern 3 — Keep it as a dev-only dependency while prototyping. If you genuinely want live updates to the stubs during a spike:
"require-dev": {
"arkecosystem/foundation": "dev-main"
}
Then composer remove --dev at the end. Never put it in require.
Layout composition. These kits almost always define a single layouts/app.blade.php with {{ $slot }} plus named sections. The day-to-day integration point is your page views:
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Dashboard') }}
</h2>
</x-slot>
<livewire:dashboard.stats />
</x-app-layout>
Verify the component namespace resolves — if the package registers components, they'll be prefixed (e.g. <x-foundation::card>). Check boot() in the service provider for Blade::componentNamespace() or loadViewComponentsAs().
Tailwind integration — the step people get wrong. Published vendor views must be scanned by Tailwind or every class in them gets purged:
// tailwind.config.js
content: [
'./resources/**/*.blade.php',
'./resources/**/*.js',
'./vendor/arkecosystem/foundation/resources/views/**/*.blade.php',
],
If you followed Pattern 1 and published the views into resources/, you're already covered — another reason to prefer publishing over referencing vendor paths.
Livewire asset wiring. Livewire 2 needs @livewireStyles in <head> and @livewireScripts before </body>; Livewire 3 injects automatically. Kits written for Livewire 2 will have these hardcoded in the layout — harmless in v3, but remove them if you see duplicate script tags or a console warning.
Merging configs. If the package ships a tailwind.config.js with custom colors/fonts, import rather than overwrite:
const foundation = require('./vendor/arkecosystem/foundation/tailwind.config.js');
module.exports = {
...foundation,
content: [/* your globs, plus foundation's */],
theme: { extend: { ...foundation.theme?.extend, /* your additions */ } },
};
The maintenance risk is the real assessment. One star, zero dependents, and a single burst of release activity means: no security patches, no Livewire 4 compatibility, no Laravel 13 support. Budget for the package to be frozen the day you adopt it. The mitigation is cheap — publish and remove — so do it on day one, not after you've built six screens against a vendor path.
Conflicts with Breeze / Jetstream. All three publish resources/views/layouts/app.blade.php, components/, and auth views. If you use Breeze for auth and this for layout, publish in a deliberate order and diff after each. vendor:publish silently skips existing files by default — meaning you can end up with a mixed layout from two kits and no error. Run git status immediately after every publish.
--force is a footgun. It overwrites your customizations with vendor defaults with zero confirmation. Never run it on a dirty working tree. Better: publish to a temp tag/directory and diff, or use Pattern 2 (clone the repo).
Config cache masking. After publishing config or views, php artisan config:clear && php artisan view:clear. In production, config:cache will happily cache a config that references a vendor path that no longer exists post-composer remove.
Tailwind purge symptom. Styling "works on some pages but not others" is almost always a content-glob problem, not a package bug. Check npx tailwindcss -i ... -o ... output for the missing classes, and confirm the glob covers where the file actually lives — resources/views/vendor/... vs resources/views/....
Livewire component-not-found errors usually mean the view was published but the component class still lives in vendor/. You can't half-publish. Either reference the vendor-namespaced component or copy the class into app/Livewire/ and rewrite the view's tag.
Debugging extension points. The service provider's boot() is the whole API surface. Read it line by line — it tells you every view namespace, component namespace, config key, and publish tag the package registers. There's no documentation worth trusting beyond that file; with a package this small, the source is the manual.
When to walk away. If composer show -a reveals constraints incompatible with your stack, or if the views depend on a Tailwind plugin you don't want, don't fight it — the package is a few hundred lines of Blade. Rebuilding the layout with Tailwind and Livewire directly takes less time than reconciling versions, and you'll understand every line.
How can I help you explore Laravel packages today?