nedarta / php-assetopt
PHP asset optimizer: a clean port of the YUI CSS compressor plus a whitespace/comment stripper for JavaScript
Requires
- php: >=8.2
- ext-pcre: *
Requires (Dev)
- cogpowered/finediff: 0.3.*
- phpunit/phpunit: ^9
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-10 23:41:48 UTC
README
Small, dependency-free PHP utility library that optimizes frontend assets (CSS and JavaScript) without external binaries such as the Java-based YUI Compressor or closure-compiler.
- CSS: whitespace-only minifier, a clean port of the YUI CSS compressor.
Optionally resolves
@importat-rules (full inlining, also remote stylesheets) before minifying. - JavaScript: whitespace/comment stripper that keeps the code fully functional without renaming anything.
- CLI: a drop-in replacement for the compressor commands used in build tools and frameworks such as Yii2's AssetManager.
Requirements
- PHP 8.2 or higher
- PCRE PHP extension
Installation
composer require nedarta/php-assetopt
Note: composer.phar install is needed to run the tests, GUI or CLI utilities within the repository downloaded from GitHub.
Usage
PHP
use nedarta\AssetOpt\Minifier; $compressedCss = (new Minifier)->run($css);
use nedarta\AssetOpt\JsStrip; $compressedJs = (new JsStrip)->compress($js);
Resolving @import at-rules (local relative paths and remote http/https urls) before minifying:
use nedarta\AssetOpt\ImportResolver; use nedarta\AssetOpt\Minifier; // css with @import at-rules $css = file_get_contents('path/to/styles.css'); // resolve @import at-rules: $baseDir for relative @import urls $css = (new ImportResolver)->resolve($css, 'path/to'); // minify resolved css $compressedCss = (new Minifier)->run($css);
use nedarta\AssetOpt\Minifier as CSSmin; $cssmin = new Minifier([ /* Raise PHP limits */ 'raise_php_limits' => true ]); $cssmin->setMaxExecutionTime(30); // Set maximum execution time to 30 seconds by default $cssmin->setPcreBacktrackLimit(2000000); // Set PCRE backtrack limit to 2 x 2 by default $cssmin->setPcreRecursionLimit(500000); // Set PCRE recursion limit to 5 x 0.5 by default $cssmin->keepSourceMapComment(); // Keeps sourcemap special comment in the output by default $cssmin->removeImportantComments(); // Removes !important comments in the output by default $cssmin->setLineBreakPosition(500); // Set line break position $compressedCss = $cssmin->run($css);
CLI
The CLI allows both the option-style commands used by the original YUI Compressor port, and the positional {from} {to}-style commands used in e.g. Yii2's AssetManager.
Use --type js to strip JavaScript, or --type css (the default) to minify CSS:
$ cd <pkg-root-folder> $ composer install $ ./vendor/bin/assetopt -i ./my-css-file.css -o ./my-css-file.min.css
Output compression result to another file:
./vendor/bin/assetopt -i ./my-css-file.css -o ./my-css-file.min.css
Minify JavaScript:
./vendor/bin/assetopt --type js ./my-js-file.js -o ./my-js-file.min.js
Output minified CSS code to standard output:
./vendor/bin/assetopt -i ./my-css-file.css
YUI-compressor-style commands (the --type flag selects the pipeline, --disable-optimizations is accepted and ignored):
# the following commands are equivalent (css minification) ./vendor/bin/assetopt --type css ./my-css-file.css -o ./my-css-file.min.css ./vendor/bin/assetopt --type css --disable-optimizations -i ./my-css-file.css -o ./my-css-file.min.css # JavaScript ./vendor/bin/assetopt --type js --disable-optimizations -i ./my-js-file.js -o ./my-js-file.min.js
Merge and minify several external CSS files into one file (files are processed in the given order, duplicate @charset rules are removed automatically):
./vendor/bin/assetopt -i ./reset.css -i ./layout.css -o ./main.min.css
Keep sourcemap comments in the output:
# note that this option only has an effect when minifying CSS
./vendor/bin/assetopt -i ./my-css-file.css -o ./my-css-file.min.css --keep-sourcemap
Remove /*! ... */ important comments from the output:
./vendor/bin/assetopt -i ./my-css-file.css -o ./my-css-file.min.css --remove-important-comments
Inline stylesheets pointed to by @import at-rules (local relative paths and remote http/https urls) before minifying — imported stylesheets are resolved recursively, imported files declaring media queries are wrapped in the equivalent @media block:
./vendor/bin/assetopt -i ./my-css-file.css -o ./my-css-file.min.css --resolve-imports
See the binary help (./vendor/bin/assetopt --help) for all available options.
Framework integration (Yii2 example)
Use the library's CLI as a drop-in replacement for legacy Java-based compressors. The asset bundle configuration itself stays unchanged — you only switch the compressor commands in the application config:
/** * Simple Yii2 AssetBundle with minification of contents * of its $css and $js files in the production environment. */ class AppAsset extends AssetBundle { public $sourcePath = '@app/assets'; public $css = [ 'css/app.css', 'https://fonts.googleapis.com/css?family=PT+Serif:400,700,400italic,700italic', ]; public $js = [ 'js/app.js', ]; public $depends = [ \yii\web\JqueryAsset::class, \yii\bootstrap\BootstrapAsset::class, ]; ... }
Below the assetManager snippet to put in application config, e.g. config/web.php:
'components' => [ 'assetManager' => [ 'forceCopy' => YII_DEBUG, 'linkAssets' => true, // compress css and js assets of the app 'compress' => !YII_DEBUG, 'cssCompressor' => 'php vendor/bin/assetopt {from} -o {to}', 'jsCompressor' => 'php vendor/bin/assetopt --type js {from} -o {to}', ], ],
This replaces the typical Java-tool configuration (taken as reference of what the above switch replaces):
'components' => [ 'assetManager' => [ // ... the settings above can replace tools such as: 'cssCompressor' => 'java -jar yuicompressor-2.4.8.jar --disable-optimizations --type css {from} -o {to}', 'jsCompressor' => 'java -jar closure-compiler-v20250820.jar --js {from} --js_output_file {to} --warning_level=QUIET', ], ],
Notes for Yii2:
cssCompressor/jsCompressorreceive{from}and{to}absolute paths; assetopt treats the input as a positional argument and-o {to}as the output option, matching both templates shown above.--warning_level=QUIETand--disable-optimizationsstyle flags are accepted and ignored, so a previous configuration can keep working almost verbatim.- closure-compiler removes dead/redundant code and renames symbols, assetopt never alters code semantics — if you rely on those optimizations consider keeping esbuild/terser around for JS and using
assetoptfor CSS only.
GUI
We've made a simple web based GUI to use the compressor, it's in the gui folder.
GUI features:
- Optional on-the-fly LESS compilation before compression with error reporting included.
- Absolute control of the library.
How to use the GUI:
- You need a server with PHP 8.2+ installed.
- Download the repository and upload it to a folder in your server.
- Run
composer installin project's root to install dependencies. - Open your favourite browser and enter the URL to the
/guifolder.
Tests
Tests from YUI compressor have been modified to fit this port. Run all tests:
$ cd <pkg-root-folder> $ composer.phar install $ ./vendor/bin/phpunit
API Reference
__construct ([ bool $raisePhpLimits ])
Creates a new minifier instance.
- $raisePhpLimits: (bool). If true, PHP settings inherited from default values like execution time limit will be raised when values are not enough to process very big CSS code. Default: true
run (string $css)
Takes a CSS string of code to be minified, returning the compressed CSS code if everything is OK; throwing an Exception if the code could not be minified.
- $css: (string). CSS code to be minified.
keepSourceMapComment (bool $keepSourceMap)
Keeps the sourcemap special comment (/*# sourceMappingURL=... */) after the end of the minification.
- $keepSourceMap: (bool). If false, sourcemap comments will be removed by default.
removeImportantComments (bool $removeImportantComments)
Removes /*! ... */ special comments — typically license headers — from the minified output.
- $removeImportantComments: (bool). If false, important comments won't be removed.
setLinebreakPosition (int $position)
Better readability of minified CSS could be achieved splitting the output after a specific position, e.g. a column value around 500 characters.
- $position: (int). Every 256 characters by default.
setMaxExecutionTime (int $seconds)
Sets the max PHP execution time allowed to minify.
- $seconds: (int). PHP max execution time limit, as specified in php.ini. Read this section from provided
php.iniby default.
setMemoryLimit (mixed $limit)
Raised PHP memory limits on minification.
- $limit: (mixed). PHP memory limit, as specified in php.ini. Read this section from provided
php.iniby default.
setPcreBacktrackLimit (int $limit)
Raised PCRE backtrack limits on minification.
- $limit: (int). Backtrack limit as specified in
php.ini, 10 times the default (2 MB) is applied by default.
setPcreRecursionLimit (int $limit)
Raised PCRE recursion limits on minification.
- $limit: (int). Recursion limit as specified in
php.ini, 5 times the default (500k) is applied by default.
Credits and provenance
This package is based on the following building blocks — big thanks to the original authors:
- YUI CSS compressor (C) 2009-2011 Yahoo! Inc. — part of the YUI Compressor, BSD license.
- YUI-CSS-compressor-PHP-port by Tobal Martín (tubalmartin/MojoYUIcompressor etc.), a PHP port of the above. This package started as a modernized fork of it, and the CSS minifier is essentially the successor of that code.
- splitbrain/php-jsstrip by Andreas Gohr, vendored into
src/JsStrip.php(BSD-3-Clause) — itself a PHP port of Nick Galbreath'sjsstrip.py. - FineDiff by Stephen Clay, vendored under
tests/FineDiffto compare minified output against the original test suite expectations.
The compressor implementation remains faithful to the original YUI compressor behavior, with the port optionally inlining @import rules, wiring JavaScript support, and dropping obsolete workarounds for legacy PHP versions.
Changelog
v1.0.0
First release of this package.
- CSS minifier ported from
tubalmartin/YUI-CSS-compressor-PHP-portwith namespacenedarta\AssetOpt - PHP 8.2+ support, PHPUnit 9 test suite
JsStripJS whitespace/comment stripper (fromsplitbrain/php-jsstrip)ImportResolver+--resolve-imports: full recursive@importinlining (local paths, remote http/https)- CLI rewritten: positional
{from} -o {to}invocations,--type js|cssselection, inline--opt=valuevalues,--typeand--disable-optimizationsyuicompressor.jar flags accepted and ignored - Fixed minification of empty custom property values like
--var: ;(emitted by Sass for undefined variables)
History
For project history prior to this version, see the legacy YUI-CSS-compressor-PHP-port repositories (upstream original port by Tobal Martín, and the interim fork nedarta/cssmin).