leafo/scssphp
leafo/scssphp is a PHP compiler for SCSS/Sass. Use it to compile .scss files to CSS in PHP apps, with support for variables, nesting, mixins, imports, and more. Handy for build pipelines, theming, or on-the-fly stylesheet generation.
Installation:
composer require leafo/scssphp
Add to composer.json under require-dev if only needed for builds:
"require-dev": {
"leafo/scssphp": "^0.7.2"
}
Basic Compilation:
use Leafo\ScssPhp\Compiler;
$compiler = new Compiler();
$scss = file_get_contents('resources/scss/app.scss');
$css = $compiler->compile($scss);
file_put_contents('public/css/app.css', $css);
First Use Case:
$compiler = new Compiler();
$compiler->setImportPaths(['resources/scss']);
$css = $compiler->compile('@import "variables"; @import "base";');
Compiler.php for core logic and Functions.php for custom functions.tests/ directory for usage examples and edge cases.Development Workflow (Watch Mode): Use a file watcher (e.g., Laravel Mix, custom script) to recompile on file changes:
$compiler = new Compiler();
$compiler->setImportPaths(['resources/scss', 'node_modules']);
$compiler->setOutputStyle(Compiler::OUTPUT_STYLE_COMPRESSED); // or NORMAL
// Recompile on file change (pseudo-code)
while (true) {
if (filemtime('resources/scss/app.scss') > $lastModified) {
$css = $compiler->compile(file_get_contents('resources/scss/app.scss'));
file_put_contents('public/css/app.css', $css);
$lastModified = filemtime('resources/scss/app.scss');
}
sleep(1);
}
Laravel Integration:
$this->app->singleton(Compiler::class, function () {
$compiler = new Compiler();
$compiler->setImportPaths([
resource_path('scss'),
base_path('node_modules')
]);
return $compiler;
});
use Leafo\ScssPhp\Compiler;
class ScssCompileCommand extends Command
{
protected $signature = 'scss:compile {--watch}';
public function handle(Compiler $compiler) {
$scss = file_get_contents('resources/scss/app.scss');
$css = $compiler->compile($scss);
file_put_contents('public/css/app.css', $css);
if ($this->option('watch')) {
$this->watchForChanges($compiler);
}
}
}
Custom Functions: Extend SCSS with PHP functions:
$compiler = new Compiler();
$compiler->addFunction('my-custom-function', function ($arguments) {
return 'custom-value';
});
$scss = '$var: my-custom-function();';
$css = $compiler->compile($scss);
Output Styles:
Toggle between OUTPUT_STYLE_NORMAL, OUTPUT_STYLE_COMPRESSED, or OUTPUT_STYLE_EXPANDED based on environment:
$compiler->setOutputStyle(
config('app.env') === 'production'
? Compiler::OUTPUT_STYLE_COMPRESSED
: Compiler::OUTPUT_STYLE_NORMAL
);
Cache Compiled CSS: Use Laravel's cache to avoid recompiling unchanged files:
$cacheKey = 'scss_app_css';
if (!Cache::has($cacheKey)) {
$css = $compiler->compile(file_get_contents('resources/scss/app.scss'));
Cache::put($cacheKey, $css, now()->addHours(1));
} else {
$css = Cache::get($cacheKey);
}
Asset Pipeline: Combine with Laravel Mix or Vite for a hybrid workflow (e.g., compile SCSS in PHP, then process with JS tools).
Error Handling: Wrap compilation in a try-catch to handle SCSS errors gracefully:
try {
$css = $compiler->compile($scss);
} catch (\Exception $e) {
Log::error('SCSS Compilation Error: ' . $e->getMessage());
$css = file_get_contents('public/css/fallback.css');
}
Deprecated Features:
@use, @forward). Stick to @import and avoid cutting-edge syntax.Performance:
OUTPUT_STYLE_COMPRESSED in production.Path Handling:
['/absolute/path/to/scss']). Relative paths may break in shared hosting.@import statements.Custom Functions:
$compiler->addFunction('safe-divide', function ($args) {
if (count($args) !== 2) {
throw new \Exception('safe-divide requires 2 arguments');
}
return $args[0] / $args[1];
});
Output Quirks:
scss --source-map) if needed.Enable Verbose Output:
Set the verbose flag to debug compilation issues:
$compiler->setVerbose(true);
$css = $compiler->compile($scss); // Errors will be logged to stderr.
Check for Deprecated Syntax:
@import "test";
body { color: red; }
Memory Limits:
Increase PHP's memory_limit if compilation fails:
ini_set('memory_limit', '512M');
Pre/Post-Processing:
Hook into compilation with addFunction or extend the Compiler class:
class CustomCompiler extends Compiler {
public function compile($scss) {
$scss = $this->preProcess($scss);
$css = parent::compile($scss);
return $this->postProcess($css);
}
}
Plugin System: Create a plugin architecture for reusable configurations:
class ScssPlugin {
public static function configure(Compiler $compiler) {
$compiler->setImportPaths([...]);
$compiler->addFunction('plugin-function', fn($args) => '...');
}
}
Fallback for Missing Features: Use a hybrid approach (PHP + Node.js):
if (class_exists('Leafo\ScssPhp\Compiler')) {
// Use scssphp
} else {
// Fallback to Node.js (e.g., via exec)
exec('node-sass resources/scss/app.scss public/css/app.css');
}
Default Import Paths: The compiler starts with no import paths. Always set them explicitly:
$compiler->setImportPaths(['resources/scss']);
Output Style Default:
Defaults to OUTPUT_STYLE_NORMAL. Explicitly set it to avoid surprises:
$compiler->setOutputStyle(Compiler::OUTPUT_STYLE_COMPRESSED);
File Caching:
The compiler does not cache compiled files by default. Implement caching manually (e.g., with Laravel's Cache facade).
How can I help you explore Laravel packages today?