etrepat/basset
Basset is a Laravel asset management package that collects, compiles, combines, and minifies CSS and JavaScript. It supports preprocessors, asset collections, named assets, and cache-friendly URLs to simplify frontend asset pipelines.
Basset is a Laravel 4-era asset manager: you register assets (stylesheets, JS) into named collections, and Basset combines + minifies those collections and emits the correct <link>/<script> tags. The value proposition is "declare assets once, get one optimized file per collection."
1. Install
composer require etrepat/basset
2. Register the provider and alias in app/config/app.php:
'providers' => array(
// ...
'Basset\BassetServiceProvider',
),
'aliases' => array(
// ...
'Basset' => 'Basset\Facades\Basset',
),
3. Publish the config (Laravel 4 syntax):
php artisan config:publish etrepat/basset
This lands at app/config/packages/etrepat/basset/config.php. Open it first — the collections array is the heart of the package, and defaults for minification/cache behavior live here.
4. First use case — a layout-driven bundle. Add assets in a view composer or bootstrap file, output in your Blade layout:
Basset::add('css/app.css');
Basset::add('js/app.js');
<head>
{{ Basset::styles() }}
</head>
<body>
...
{{ Basset::scripts() }}
</body>
Where to look first: the config file (to see the shape of collections), then vendor/etrepat/basset/README.md for the exact Basset:: method signatures on the version you installed. Run php artisan list | grep basset to discover any cache/build commands shipped with your version.
Config-driven collections — for stable bundles that should not be re-declared in code, define them in the config file:
'collections' => array(
'base' => array(
'stylesheets' => array(
'css/reset.css',
'css/app.css',
),
'javascripts' => array(
'js/vendor/jquery.js',
'js/app.js',
),
),
),
Then emit them by name from your layout:
{{ Basset::styles('base') }}
{{ Basset::scripts('base') }}
Runtime collections via closure — handy when a bundle depends on controller/context:
Basset::collection('admin', function ($collection) {
$collection->add('css/admin.css');
$collection->add('js/admin.js');
});
Multiple collections per layout — a common real-world setup is one collection for the header (critical CSS reset/framework), one for the footer (JS), and a per-page collection injected via @section or a View::composer:
View::composer('layouts.*', function ($view) {
Basset::collection('page', function ($c) use ($view) {
foreach ($view->pageAssets as $asset) {
$c->add($asset);
}
});
});
Adding with explicit type and attributes — the signature is essentially add($asset, $type, $attributes, $alternatePath). Use $type when the extension is ambiguous, and $attributes to stamp things like media="print" or async:
Basset::add('css/print.css', 'css', array('media' => 'print'));
Basset::add('js/analytics.js', 'js', array('async' => 'async'));
CDN / external URLs — pass a full http(s):// URL and Basset leaves it alone (no combining/minifying), so you can mix vendor CDN assets with local ones in the same collection. Use $alternatePath to provide a local fallback for CDN failures.
Ordering matters — assets are emitted in the order added within a collection. Put framework/vendor files before app files, and keep one collection per load-order boundary rather than one giant collection.
Deployment integration — since combining happens through a route/cache, run any available basset artisan command as part of your deploy (or hit the collection URL once) so the combined files exist before traffic arrives. Add an invalidate/cache-clear step after git pull so stale combined files don't outlive your source changes.
Laravel version lock. This package targets Laravel 4.x — service-provider syntax, facade aliasing, and config:publish paths all reflect that. On Laravel 5+/8+ you will need to port or shim it; do not assume drop-in compatibility. Verify the composer.json constraints before starting a new project on it.
Paths are relative to public/. Basset::add('css/app.css') resolves to public/css/app.css. Assets that don't exist on disk will fail at combine time, not at add() time — so a 404 only appears when the collection route is hit. Validate each asset path in a smoke test.
Minification breaks things silently. The minifier is not a JS parser; template literals, ASI edge cases, and modern syntax can produce runtime errors that only show in the combined file. Toggle minification off in the config first when debugging a "works locally, breaks combined" bug. Treat the toggle as your primary diagnosis switch.
Cache invalidation is manual. Combined output is cached; changing a source file will not necessarily regenerate it. Wire an invalidate call (or clear the cache path) into your deploy script, and be aware of this during local dev — you may spend an hour debugging a change that never shipped.
No fingerprinting. Basset does not do content-hash cache-busting like Elixir/Mix. You'll need to append a version query string manually (?v=) or rely on cache invalidation. Plan for this before CDN caching.
Debugging the combined URL. Inspect the rendered <link>/<script> href/src in the browser and open it directly. If it 404s, the issue is route registration, cache directory permissions, or a missing source file — not your Blade template.
Attribute serialization. The $attributes array is rendered literally onto the tag; booleans and nested arrays do not behave the way you might expect. Use string values ('async' => 'async') and avoid passing nulls.
Extension points are thin. The package has no formal asset-compiler pipeline (no SASS/LESS/ESBuild integration). For anything beyond "concatenate and minify plain CSS/JS", precompile in a separate step and hand Basset only the final .css/.js files — treat Basset as the last mile, not the build system.
Abandonment risk. With ~14 stars and no active maintenance, budget for replacing it (Laravel Mix, Vite, laravel-elixir) if this is a long-lived project. The migration surface is small if you centralize asset declarations behind a single service provider, so keep that indirection even while using Basset.
How can I help you explore Laravel packages today?