##############
From htmlmin
##############
.. package-meta:: htmlmin mankyd/htmlmin
`htmlmin `_ is a pure-Python HTML minifier built on the standard library's
``HTMLParser``. ``htmlmin.minify(html, **flags)`` collapses whitespace runs to a single space and can optionally drop
comments, reduce empty attributes, and remove redundant attribute quotes; ``htmlmin.Minifier`` exposes the same folds
over incremental input, and the package also ships a WSGI middleware and a decorator for minifying responses in web
frameworks. It sees wide use through those integrations in Django and Flask stacks. Its last release, 0.1.12 from 2017,
imports the ``cgi`` module Python 3.13 removed, so it no longer installs on current interpreters; the maintained
``htmlmin2`` fork restores the import but changes nothing else.
turbohtml covers the same ground with :func:`turbohtml.clean.minify`, one call that minifies a document over the WHATWG
tree turbohtml already builds, configured by the frozen :class:`~turbohtml.Minify` options object. It applies the same
whitespace, comment, and attribute folds, adds a fold htmlmin lacks (omitting the tags the WHATWG rules make optional),
and does the work in a compiled C serializer instead of a Python token loop.
**********************
turbohtml vs htmlmin
**********************
.. list-table::
:header-rows: 1
:widths: 20 40 40
- - Dimension
- turbohtml
- htmlmin
- - Scope
- Full WHATWG parser plus serializer; minify is one output layout
- HTML minification only, over ``HTMLParser``
- - Feature breadth
- Whitespace, comment, attribute-quote folds plus optional-tag omission and optional inline JS/CSS minification
- Whitespace, comment, empty-attribute, boolean-attribute, and quote folds; incremental ``Minifier``; WSGI
middleware and framework decorator
- - Performance
- C serializer over an already-built tree; 16-23x faster, parse included (see below)
- Pure-Python ``HTMLParser`` token loop
- - Typing
- Fully typed, frozen :class:`~turbohtml.Minify` options object
- Untyped ``**flags`` keyword arguments
- - Dependencies
- Self-contained C extension, no runtime dependencies
- Pure Python; last release does not install on Python 3.13+ (use ``htmlmin2``)
- - Maintenance
- Actively maintained
- Upstream last released 2017; community ``htmlmin2`` fork carries compatibility fixes only
Feature overlap
===============
These folds port one-to-one; each htmlmin flag becomes a field on :class:`~turbohtml.Minify`:
- Whitespace collapsing — ``htmlmin.minify(html)`` (on by default) maps to ``Minify(collapse_whitespace=True)`` (also
the default).
- Comment removal — ``remove_comments=True`` maps to ``Minify(strip_comments=True)`` (the turbohtml default; comments go
unless you opt out).
- Attribute-quote removal and empty-attribute reduction — ``remove_optional_attribute_quotes`` and
``reduce_empty_attributes`` map to the single ``Minify(unquote_attributes=True)``, which also collapses an empty value
to a bare attribute name.
What turbohtml adds
===================
- Optional-tag omission — ``Minify(omit_optional_tags=True)`` drops the start and end tags the WHATWG rules make
optional (````, ``
``, ````, and so on). htmlmin keeps every tag.
- Character-reference resolution — ``é`` serializes as the shorter literal ``é``; htmlmin passes references
through unchanged.
- Inline JavaScript minification — ``Minify(minify_js=JSMinify())`` rewrites ``