This is a minifier for CSS, JavaScript, XML and HTML, written in C. It is designed according to the following requirements:
-
Released as single binary with no dependencies except libc.
-
Produce standard-conform output from any standard-conform input.
-
The program should fail on syntax errors and must not fix them.
-
This minifier is not a cleaner. It should not modify the semantics of the markup.
-
Specifially, non-objectives are cleanups that can (and should) be done in the source code if they don't decrease the legibility. Detection of such optimization potential is in the scope of a linter. Linting may be added in the future but it would be a separate functionality.
- Not removing empty CSS rules. Why would you have empty rules in the released code?
- No merging of CSS properties.
- Not removing doctypes or XML headers. They do have a meaning.
- Minification of colors is a possible future objective because doing it in the source code can decrease its legibility.
- More advanced JavaScript minification is a possible future objective. Shortening variable names would provides the most minification potential.
-
Cleaning exported SVG files is better done with a cleaner such as
svgcleaner
. With default options, such cleaners substantially modify the markup semantically, which may be desired for exported SVG files but not for hand-written ones. This minifier is suitable to minify hand-written SVG files.A useful manual cleaning recipe for exported SVG files may be:
svgcleaner picture.svg clean.svg XMLLINT_INDENT=" " xmllint --format clean.svg > picture.svg rm clean.svg
This generates standard-compliant XML files with indentation to enable manual inspection or adjustment. In a Makefile one can run this minifier on the result to create the release.
Some alternative minifiers choose different objectives.
-
Many minifiers use advanced minification strategies that require large dependencies to parse the input into an abstract syntax tree. Usually they are focused on only one input format and provide many configuration options. If you want maximum minification, prefer such specialized tools.
This minifier is rather focused on maximizing the web developer productivity: having only one lightweight tool with few options to handle all relevant formats. Moreover its approach enables the best possible runtime performance by looping through the input in a single pass.
-
Some minifiers semantically alter the content of the input files, such as fixing errors or removing doctypes, version tags, XML namespaces and encoding information.
Besides the fact that some of the information can be relevant, my opinion is that these are different concerns that should be handled by separate tools, namely linters or cleaners, and that a minifier should assume (or assert) perfect quality of the input files.
To illustrate why these are separate concerns, consider that minifiers (and linters) are supposed to run automatically in every build process, whereas cleaners or fixers are rather run manually.
-
Some minifiers are quite fault-tolerant. However, if garbage is fed into a minifier then there is a problem somewhere else in the tool or process chain that is good to be alerted about. Strict parsing is a good practice to promote standard conformity.
https://github.com/tdewolff/minify
Written in Go. Minifies HTML, XML, SVG, JS, CSS, JSON. It is in the package repository of Alpine Linux and statically linked binary releases exist.
https://github.com/csstidy-c/csstidy
Written in C++, not maintained. Prints lots of warnings on valid input.
https://csstidy.sourceforge.net/usage.php
https://github.com/cssnano/cssnano
Written in JavaScript.
https://github.com/clean-css/clean-css
Written in JavaScript.
https://github.com/parcel-bundler/lightningcss
Written in Rust.
https://github.com/fmarcia/uglifycss
Written in JavaScript.
https://yui.github.io/yuicompressor/
Written in Java.
https://github.com/matthiasmullie/minify
Written in PHP. Based on regex, hence it breaks on standard-conform input such as:
@import url(http://example.org/*)/**/;
http://opensource.perlig.de/rcssmin/
Written in Python. Based on regex.
https://github.com/mishoo/UglifyJS
https://github.com/RazrFalcon/svgcleaner
Written in Rust.
Written in JavaScript / NodeJS.
https://github.com/scour-project/scour
Written in Python.
Here we have two very good options with no big dependencies. I still included XML and HTML minification in this minifier to cover all needs with one tool.
Written in C.
xmllint
as part of libxml2 (https://gitlab.gnome.org/GNOME/libxml2)
Written in C.