https://github.com/openwisp/django-minify-compress-staticfiles
A modern Django package for minifying and compressing static files during collectstatic with minimal configuration.
https://github.com/openwisp/django-minify-compress-staticfiles
Last synced: 2 months ago
JSON representation
A modern Django package for minifying and compressing static files during collectstatic with minimal configuration.
- Host: GitHub
- URL: https://github.com/openwisp/django-minify-compress-staticfiles
- Owner: openwisp
- License: bsd-3-clause
- Created: 2026-01-28T23:50:44.000Z (5 months ago)
- Default Branch: master
- Last Pushed: 2026-01-31T23:33:06.000Z (5 months ago)
- Last Synced: 2026-03-12T20:33:06.638Z (4 months ago)
- Language: Python
- Homepage:
- Size: 76.2 KB
- Stars: 2
- Watchers: 0
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.rst
- License: LICENSE
Awesome Lists containing this project
README
Django Minify Compress StaticFiles
==================================
.. image:: https://github.com/openwisp/django-minify-compress-staticfiles/workflows/CI/badge.svg
:target: https://github.com/openwisp/django-minify-compress-staticfiles/actions
:alt: CI build status
.. image:: https://coveralls.io/repos/github/openwisp/django-minify-compress-staticfiles/badge.svg?branch=master
:target: https://coveralls.io/github/openwisp/django-minify-compress-staticfiles?branch=master
:alt: Coverage
.. image:: https://badge.fury.io/py/django-minify-compress-staticfiles.svg
:target: https://badge.fury.io/py/django-minify-compress-staticfiles
:alt: PyPI Version
.. image:: https://img.shields.io/badge/License-BSD%203--Clause-blue.svg
:target: https://opensource.org/licenses/BSD-3-Clause
:alt: License
A modern Django package for minifying and compressing static files during
``collectstatic`` with minimal configuration.
Features
--------
- **CSS/JS Minification**: Uses ``rjsmin`` and ``rcssmin`` for fast
minification
- **Dual Compression**: Gzip and Brotli compression support
- **Django Integration**: Seamless integration with Django's static file
system
- **Selective Processing**: Only processes appropriate file types
- **Minified Filename Format**: Preserves Django's hash and adds ``.min``
before the extension: ``name.{hash}.min.ext``. This allows precompressed
files to be properly served as ``name.{hash}.min.ext.gz`` and
``name.{hash}.min.ext.br``.
- **Configurable**: Fine-grained control over processing options
Installation
------------
Install from PyPI:
.. code-block:: bash
pip install django-minify-compress-staticfiles
Configuration
-------------
For **Django 4.2+**, update your ``STORAGES`` setting:
.. code-block:: python
STORAGES = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
},
"staticfiles": {
"BACKEND": "django_minify_compress_staticfiles.storage.MinicompressStorage",
},
}
For **Django < 4.2**, use the legacy setting:
.. code-block:: python
STATICFILES_STORAGE = "django_minify_compress_staticfiles.storage.MinicompressStorage"
Settings
--------
All settings use the ``MINICOMPRESS_`` prefix:
``MINICOMPRESS_ENABLED``
Enable/disable processing (default: ``True``)
``MINICOMPRESS_MINIFY_FILES``
Enable CSS/JS minification (default: ``True``)
``MINICOMPRESS_GZIP_COMPRESSION``
Enable Gzip compression (default: ``True``)
``MINICOMPRESS_BROTLI_COMPRESSION``
Enable Brotli compression (default: ``True``)
``MINICOMPRESS_MIN_FILE_SIZE``
Minimum file size for compression in bytes (default: ``200``)
``MINICOMPRESS_MAX_FILE_SIZE``
Maximum file size for processing in bytes (default: ``10485760``,
i.e., 10MB) Files larger than this are skipped to prevent memory
exhaustion. Adjust based on your available memory and security
requirements.
``MINICOMPRESS_MAX_FILES_PER_RUN``
Maximum number of files to process per ``collectstatic`` run (default:
``1000``) Prevents CPU and memory exhaustion when processing large
numbers of files. Increase only if you have verified your system can
handle it.
``MINICOMPRESS_COMPRESSION_LEVEL_GZIP``
Gzip compression level (default: ``6``, range: 0-9) Level 6 provides a
good balance between compression ratio and CPU usage. Higher values
(8-9) consume significantly more CPU with diminishing returns. Lower
values (0-5) are faster but produce larger compressed files.
``MINICOMPRESS_COMPRESSION_LEVEL_BROTLI``
Brotli compression quality (default: ``4``, range: 0-11) Level 4
offers excellent compression with reasonable CPU usage. Higher values
(8-11) can cause severe CPU spikes during ``collectstatic``. Lower
values (0-3) are faster but less effective compression.
``MINICOMPRESS_PRESERVE_COMMENTS``
Preserve bang comments in CSS/JS (default: ``True``)
``MINICOMPRESS_SUPPORTED_EXTENSIONS``
Dictionary of file extensions to process (default: css, js, txt, xml,
json, svg, md, rst, html, htm)
``MINICOMPRESS_EXCLUDE_PATTERNS``
List of glob patterns to exclude from processing (default:
``["*.min.*", "*-min.*", "*swagger-ui-*", "*.gz", "*.br", "*.zip"]``)
Pre-compressed files (e.g., ``.gz``, ``.br``, ``.zip``) are excluded
by default to prevent double-compression and security issues.
Usage
-----
Run ``collectstatic`` as usual:
.. code-block:: bash
python manage.py collectstatic --noinput
The package will automatically:
- Minify CSS and JavaScript files
- Create ``.gz`` and ``.br`` compressed versions
- Update Django's manifest with minified file paths
- Skip already processed files and patterns
Supported File Types
--------------------
**Minification**: CSS, JavaScript
**Compression**: CSS, JS, TXT, XML, JSON, SVG, MD, RST, HTML, HTM
Security and Performance Considerations
---------------------------------------
The package implements the following safeguards to mitigate common attack
vectors and ensure resource stability.
Path Traversal Protection
~~~~~~~~~~~~~~~~~~~~~~~~~
To prevent directory traversal attacks (e.g., ``../etc/passwd``), all file
paths undergo strict validation. The system enforces a boundary check
ensuring no read or write operations occur outside the defined
``STATIC_ROOT``. Any attempt to access parent directories via relative
paths is intercepted and blocked.
Memory Exhaustion Prevention
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To prevent memory exhaustion, the ``MAX_FILE_SIZE`` setting enforces a
hard cap on file processing. This prevents the application from attempting
to buffer or process excessively large files that could lead to
Out-Of-Memory (OOM) errors.
CPU Exhaustion & Resource Throttling
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Compression is a CPU-intensive task. To balance throughput with system
stability, the default compression levels are tuned for efficiency:
- **Gzip:** Level 6
- **Brotli:** Level 4
These defaults prevent "CPU pinning" where a single request monopolizes
processor cycles.
Compression Bomb Protection
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The processor automatically excludes files that are already compressed
(e.g., ``.gz``, ``.br``, ``.zip``, ``.png``). This prevents recursive
compression cycles and "Zip Bomb" style attacks that could lead to
exponential CPU and disk space consumption.
Integrity & Cache Validation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
File fingerprinting uses **MD5** hashing to match Django's
``ManifestFilesMixin`` algorithm. This ensures consistency between
Django's hashed filenames and our minified filenames, allowing the
manifest to correctly map original files to their minified versions.
Recommended Settings for Production
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For production deployments with high security requirements:
.. code-block:: python
MINICOMPRESS_MAX_FILE_SIZE = 2097152 # 2MB
MINICOMPRESS_MAX_FILES_PER_RUN = 500
MINICOMPRESS_COMPRESSION_LEVEL_GZIP = 6
MINICOMPRESS_COMPRESSION_LEVEL_BROTLI = 4
For development environments with faster builds:
.. code-block:: python
MINICOMPRESS_COMPRESSION_LEVEL_GZIP = 1
MINICOMPRESS_COMPRESSION_LEVEL_BROTLI = 0
MINICOMPRESS_BROTLI_COMPRESSION = False # Disable for faster builds
Dependencies
------------
**Required**:
- Django >= 4.2
- Python >= 3.10
- ``brotli`` >= 1.0.0
- ``rjsmin`` >= 1.2.0
- ``rcssmin`` >= 1.1.0
License
-------
BSD 3-Clause License. See ``LICENSE`` file for details.
Contributing
------------
Contributions are welcome! Please see the `OpenWISP contributing
guidelines`_ for more information.
.. _openwisp contributing guidelines: https://openwisp.io/docs/stable/developer/contributing.html
Support
-------
- `Issue Tracker`_
- `OpenWISP Support`_
.. _issue tracker: https://github.com/openwisp/django-minify-compress-staticfiles/issues
.. _openwisp support: https://openwisp.org/support/