xrow/sass-bundle
xrow/sass-bundle is a Symfony bundle that integrates Sass/SCSS compilation into Symfony applications. It provides configuration and services to compile Sass stylesheets as part of your asset workflow, simplifying frontend styling for Symfony projects.
Read this first: it is not a Laravel package. xrow/sass-bundle is a Symfony bundle. It ships a Bundle subclass, a DependencyInjection extension, and a config tree that Laravel's container will never load. A composer require xrow/sass-bundle in a Laravel app gets you classes on disk and nothing else — no service provider, no auto-discovery, no Blade integration.
So "getting started" splits into two realistic paths.
Path A — you actually have a Symfony app (the intended use case):
composer require xrow/sass-bundleapp/AppKernel.php (Symfony 2/3 era) or config/bundles.phpDependencyInjection/Configuration.php before writing any YAML — that file is the ground truth for config keys, since the README from 2016 is unlikely to match what the code expects.<link> to a compiled stylesheet or inlines the CSS).Path B — you are a Laravel developer (the realistic case): don't install it. You have two genuinely good options:
sass npm package. npm i -D sass, point laravel-vite-plugin at your .scss entry, @vite(['resources/scss/app.scss']). You get HMR, source maps, minification, PostCSS/Tailwind, and hashed filenames for free.scssphp/scssphp directly, not this bundle: composer require scssphp/scssphp, then (new Compiler())->compileString($scss)->getCss() behind a cached service.Your first concrete use case on Path B is almost always the same: compile resources/scss/app.scss into a versioned asset at build time. Vite solves it in ten minutes.
If you are borrowing the idea rather than the package (the only sane way to "use" this in Laravel), wrap a compiler in a service provider:
// app/Providers/SassServiceProvider.php
$this->app->singleton(SassCompiler::class, fn () => new SassCompiler(
basePath: resource_path('scss'),
cachePath: storage_path('app/sass'),
));
Then expose it as a Blade directive so templates stay clean:
Blade::directive('sass', fn ($expr) => "<?php echo app(SassCompiler::class)->inline($expr); ?>");
{{-- inline critical CSS for above-the-fold --}}
<style>@sass('critical.scss')</style>
Build-time vs. request-time — pick one per use case. Runtime compilation of a large stylesheet on every request will dominate your TTFB. The pattern that works: compile at build time for the app shell, reserve runtime compilation for a small, bounded set of partials whose inputs are genuinely dynamic, and cache aggressively keyed on a hash of the inputs.
Cache keyed on inputs, not time:
$key = 'sass:' . md5($source . json_encode($variables));
return Cache::rememberForever($key, fn () => $compiler->compile($source, $variables));
Invalidate in your deploy script (or php artisan cache:clear on release), not with a TTL.
Variable injection is the one thing runtime Sass buys you over Vite. Prepend a generated $primary: #ff0000; block to the source string before compiling, rather than string-replacing inside the .scss.
CI/CD: compile in the pipeline (npm step or a php artisan sass:build command you wrote), store output under public/build with a content hash, and let the manifest resolve paths. Commit nothing generated.
If you are on Symfony and stuck with the bundle: treat the Twig extension as the only public API, keep config in config.yml under the bundle's namespace, and make sure the output directory is writable by the web user if it compiles at request time.
AppKernel, getContainerExtension), and no PHP 8 / Symfony 6 compatibility. Any modern project will hit fatal errors during container compilation, not at runtime — so a failed composer require is the best outcome you can hope for.exec/shell_exec calls — a Sass bundle of this era may shell out to a sass binary and make path assumptions that are dangerous in a web context.cache:clear is actually the trigger.scalarNode/arrayNode builders that reject keys added in later Symfony versions. If your config.yml "looks right" but the container blows up, diff your keys against DependencyInjection/Configuration.php character by character.scssphp instead.scssphp/scssphp for the narrow runtime case; both are maintained, both have docs that match the code, and neither will cost you a weekend on container errors.How can I help you explore Laravel packages today?