PHPackages                             yahyaerturan/minifier - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. yahyaerturan/minifier

ActiveLibrary[Templating &amp; Views](/categories/templating)

yahyaerturan/minifier
=====================

HTML/JS/CSS minifier with template-awareness for PHP 8.4.

v1.0.0(6mo ago)09MITPHPPHP ^8.4CI passing

Since Nov 5Pushed 6mo agoCompare

[ Source](https://github.com/yahyaerturan/minifier)[ Packagist](https://packagist.org/packages/yahyaerturan/minifier)[ Docs](https://github.com/yahyaerturan/minifier)[ RSS](/packages/yahyaerturan-minifier/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (3)Versions (2)Used By (0)

YahyaErturan Minifier (HTML/JS/CSS, template-aware)
===================================================

[](#yahyaerturan-minifier-htmljscss-template-aware)

A conservative, production-ready minifier for HTML with embedded CSS/JS and JSON. It’s template-aware (Mustache/Handlebars/Twig-style tokens), safe around `` landmines, and intentionally avoids risky AST rewrites.

- Zero dependencies, PHP 8.4+
- Template fences: `{{ }}`, `{{{ }}}`, `{% %}`, `{# #}`, `[[ ]]` are protected and restored
- Robust `` handling: finds the real closing tag while skipping strings, comments, template literals, and CDATA
- Sentinel escape: `` → `` inside JS/JSON to prevent HTML parser bail-outs
- Conservative JS/CSS: strips comments, collapses whitespace safely; preserves `/*! … */` **and** comments with `@license`/`@preserve` **verbatim**
- JSON scripts (`application/ld+json`): minified via `json_decode`/`json_encode` with a safe fallback for not-strictly-valid inputs
- Inline `style=""` compacted using the same CSS minifier
- Whitespace collapsed outside `pre/code/textarea/script/style` **without** stripping inter-tag spaces that can be visually significant (no global `>minify($html);
```

What you get by default:

- HTML comments removed except conditional ``
- Inline `` and `style=""` compacted
- `` bodies minified for classic JS + modules, `` escaped
- `application/ld+json` compacted structurally
- Templating tokens fenced and restored

---

Ignore controls (escape hatches)
--------------------------------

[](#ignore-controls-escape-hatches)

Sometimes a third-party snippet or unusual markup breaks when minified. Use these “do not touch” controls.

### HTML directives (comments)

[](#html-directives-comments)

- Region pair:

    - ` … `
    - The enclosed region is bypassed entirely (no minification, no sentinel escaping). The control comments themselves are removed.
- One-shot:

    - ` …`
    - ` …`
    - The very next ``/`` is output verbatim; control comment removed.

### Per-tag attributes

[](#per-tag-attributes)

- On `` or ``:
    - `data-minify="off"` → do not minify the tag body. For ``, the **sentinel escape still applies** for safety.
    - `data-minify="raw"` → output the tag verbatim (no minify, no sentinel escape). Sharp tool; use only when you truly need raw.
- The `data-minify` attribute is **stripped** from the output (build hint does not leak).
- **Unquoted attributes are supported**: `type=module`, `data-minify=off|raw` work the same as quoted.

---

Options
-------

[](#options)

```
final class Options
{
    public function __construct(
        // HTML
        public bool $collapseHtmlWhitespace = true,
        public bool $removeHtmlComments = true,
        public bool $preserveBangHtmlComments = true,
        public bool $preserveConditionalComments = true,

        // Inline assets
        public bool $minifyInlineCss = true,
        public bool $minifyInlineJs = true,

        // JS
        public bool $removeJsComments = true,
        public bool $preserveImportantJsComments = true, // /*! … */ or @license/@preserve kept verbatim
        public bool $retainScriptSentinel = true,        // keep /*  */ when removed comments had

        // CSS
        public bool $removeCssComments = true,
        public bool $preserveImportantCssComments = true, // /*! … */

        // JSON scripts
        public bool $minifyJsonScripts = true,

        // Template tokens
        public array $templateDelimiters = [
            ['{{{','}}}'],
            ['{{','}}'],
            ['{%','%}'],
            ['{#','#}'],
            ['[[',']]'],
        ],

        // Ignore directives
        public bool   $enableIgnoreDirectives = true,
        public string $ignoreOpenComment      = 'minify:off',
        public string $ignoreCloseComment     = 'minify:on',
        public string $ignoreNextComment      = 'minify:ignore-next',
        public string $ignoreAttrName         = 'data-minify',
    ) {}
}
```

Notes:

- `retainScriptSentinel`: when a removed JS comment contained `` (pre-escaped), the minifier emits a tiny placeholder `/*  */`. Why: guarantees safety if another tool concatenates content later. Trade-off: a few bytes in rare cases.
- `templateDelimiters`: longest opener wins; add your own pairs if you use a different templating engine.
- Ignore controls: `off` keeps `` safety for ``; `raw` is truly raw (no safety).

---

Script handling policy
----------------------

[](#script-handling-policy)

**Goal:** Only minify when it’s definitely JavaScript; treat known template types as opaque; always keep `` safe.

Script type / conditionAction`` with no `type`Minify JS + escape ```type="module"` (quoted or unquoted)Minify JS + escape ```type` is a recognized JS MIME: `text/javascript`, `application/javascript`, `text/ecmascript`, `application/ecmascript`, `x-javascript`Minify JS + escape ```type="application/ld+json"` or `application/json`JSON structural minify + escape ```type` is a template: `text/template`, `text/x-template`, `text/handlebars`, `text/ng-template`, `application/x-tmpl`**Skip minification** (opaque)`data-minify="off"`Do **not** minify; still escape ```data-minify="raw"`Output verbatim; **no** escapingAny other/unknown `type`Do **not** minify; **do** escape `` (defensive default)**Unquoted attribute support:** HTML allows tokens without quotes; this minifier recognizes `type=module` and `data-minify=off|raw` even when unquoted.

---

Why conservative?
-----------------

[](#why-conservative)

Pros: avoids broken pages, keeps template engines happy, plays well with CSP and weird embeds.
Cons: not byte-optimal; doesn’t rewrite semantics or identifiers.
Bottom line: use aggressive tools in CI if you need them; run this as your last line of defense in prod.

---

Framework integration (sketches)
--------------------------------

[](#framework-integration-sketches)

Laravel middleware:

```
class MinifyHtml
{
    public function handle($request, \Closure $next)
    {
        $response = $next($request);
        if (str_contains($response->headers->get('Content-Type', ''), 'text/html')) {
            $min = new \YahyaErturan\Minifier\HtmlMinifier(new \YahyaErturan\Minifier\Options());
            $response->setContent($min->minify($response->getContent()));
        }
        return $response;
    }
}
```

Symfony kernel response listener:

```
public function onKernelResponse(ResponseEvent $event): void
{
    $res = $event->getResponse();
    if (str_contains($res->headers->get('Content-Type', ''), 'text/html')) {
        $min = new \YahyaErturan\Minifier\HtmlMinifier(new \YahyaErturan\Minifier\Options());
        $res->setContent($min->minify($res->getContent()));
    }
}
```

---

Safety &amp; security
---------------------

[](#safety--security)

- **CSP:** if you hash inline scripts/styles (`'sha256-…'`), minify before computing hashes.
- **XSS:** the minifier never unescapes entities or rewrites URLs; it only strips comments and collapses whitespace. It also neutralizes `` sequences with `` to prevent HTML parser bail-out (unless you request raw).
- **Templates:** tokens are fenced and restored verbatim. If you use exotic delimiters, add them to `templateDelimiters`.
- **XSS/HTML parser:** `` sequences inside JS/JSON are always neutralized as ``.
- **Whitespace:** The minifier compresses text nodes but intentionally keeps necessary spaces between HTML tags to avoid layout/text regressions.

---

Tests &amp; QA
--------------

[](#tests--qa)

```
composer install
composer test
```

Recommended extras:

- Static analysis (PHPStan/Psalm)
- Mutation testing (Infection)
- Canary &amp; monitor

---

Known limits (by design)
------------------------

[](#known-limits-by-design)

- No AST-level JS/CSS transforms (no mangling, dead-code removal, or re-ordering).
- No DOM reflow: the HTML pass doesn’t restructure tags or attributes.
- SVG/MathML treated as regular HTML except inside `` or attributes—safer default.

---

Versioning
----------

[](#versioning)

Stable series: **1.0.x** (patch releases are backwards-compatible).

---

License
-------

[](#license)

MIT © Yahya Erturan

###  Health Score

35

—

LowBetter than 80% of packages

Maintenance67

Regular maintenance activity

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

194d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/b972ab78b12f88534b1e72cd122c7da3bd82e383515046338a10cb183693ac26?d=identicon)[yahyaerturan](/maintainers/yahyaerturan)

---

Top Contributors

[![yahyaerturan](https://avatars.githubusercontent.com/u/1583263?v=4)](https://github.com/yahyaerturan "yahyaerturan (1 commits)")

---

Tags

twigjavascriptcsshtmlminifytemplatemustache

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/yahyaerturan-minifier/health.svg)

```
[![Health](https://phpackages.com/badges/yahyaerturan-minifier/health.svg)](https://phpackages.com/packages/yahyaerturan-minifier)
```

###  Alternatives

[latte/latte

☕ Latte: the intuitive and fast template engine for those who want the most secure PHP sites. Introduces context-sensitive escaping.

1.3k15.7M683](/packages/latte-latte)[nochso/html-compress-twig

Twig extension for compressing HTML and inline CSS/Javascript

84468.6k8](/packages/nochso-html-compress-twig)[voku/html-compress-twig

Twig extension for compressing HTML

252.3M](/packages/voku-html-compress-twig)[odan/twig-assets

Caching and compression for Twig assets (JavaScript and CSS).

2223.0k4](/packages/odan-twig-assets)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
