Skip to main content

RefreshCSS 🫧

All Contributors

RefreshCSS is a Python library that removes unused classes, ids, and element selectors from CSS.

Make your CSS so fresh, so clean.

🔧 Installation

To use the refreshcss library or use the django-compressor integration

uv add refreshcss

To run refreshcss on the command-line

uvx refreshcss[cli]

⭐️ Features

  • Pure Python (no extra NodeJS build process needed)
  • Fast and spec-compliant CSS and HTML parsing
  • Filters out unused classes, ids, and elements from CSS based on HTML templates
  • Supports modern CSS syntax, including nested rules, container queries, and media queries
  • Handles Django/Jinja-style HTML templates with context-aware extraction
  • Integrates with django-compressor to clean CSS during the compress command
  • Command-line interface for use in CI/CD pipelines

⌨️ Command-line interface

uvx refreshcss[cli]

Usage: refreshcss [OPTIONS] CSS HTML...

  Remove classes, ids, and element selectors not used in HTML from CSS.

Options:
  -o, --output FILENAME  Write to file instead of stdout.
  -R, -r, --recursive    Recursively search subdirectories listed.
  --encoding TEXT        Character encoding to use when reading files. If not
                         specified, the encoding will be guessed.
  --version              Show the version and exit.
  --help                 Show this message and exit.

🗜️ Integrate with django-compressor

Add "refreshcss.filters.RefreshCSSFilter" to COMPRESS_FILTERS in the Django settings file.

COMPRESS_FILTERS = {
    "css": [
        "refreshcss.filters.RefreshCSSFilter",
        ...
    ],
    "js": [...],
}

⚙️ Library

from refreshcss import RefreshCSS, PathSite

def clean_css(css_path: Path):
    # Parse the HTML files
    site = PathSite(paths=["templates"], recursive=True)
    site.parse()

    # Get clean CSS based on the parsed HTML
    css_text = css_path.read_text()
    cleaned_css = RefreshCSS(site).clean(css_text)

    return cleaned_css

🤓 How does it work?

  1. Catalogue classes, ids, and elements that are currently being used in found HTML templates
  2. Catalogue classes, ids, elements, and at-rules in a particular CSS stylesheet
  3. Return a new CSS stylesheet that only contains rules that are actively being used by the HTML

🧐 Why?

I wanted to have a filter for django-compressor that would purge unused CSS as part of the compress step when deploying for coltrane apps. After dealing with a manual process and attempting to integrate https://purgecss.com and https://github.com/uncss/uncss I thought "this couldn't be that hard to do in Python".

Which is always the thought at the beginning of every side project... 😅

🙋 FAQ

Will this work with SPAs?

Probably not. RefreshCSS only inspects HTML templates, so if CSS classes are being changed client-side then refreshcss will not know about it.

Does this work by crawling a website URL?

Currently no, although that is a possibility in the future. PRs appreciated. 😉

Does this support HTML written in the Django Template Language?

Yes! That was a primary reason I built my own solution. 😅 Jinja might also be possible to support with some small tweaks, although it is currently untested.

Is this what people mean when they say "treeshaking"?

Maybe. 🤷

I found a bug!

Thanks for trying RefreshCSS out! Please make a PR (pull request) with a small test that replicates the bug or, if that is not possible, create a new discussion.

Node

Python

  • treeshake: I unfortunately could not get this to work on my local environment.
  • cssutils: This unfortunately seemed to choke on more modern CSS when I tested on Bulma 1.0.
  • css-optomizer

🙏 Thanks

❤️ Support

This project is supported by GitHub Sponsors and Digital Ocean.

🥳 Contributors

Tobias Bölz
Tobias Bölz

💻 📖 ⚠️

Metadata

Release files for refreshcss 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for refreshcss 0.6.0
File Size Uploaded Provenance
refreshcss-0.6.0.tar.gz 10.1 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for refreshcss 0.6.0
File Interpreter ABI Platform
refreshcss-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 22.9 kB

Release files / refreshcss-0.6.0.tar.gz

Download URL refreshcss-0.6.0.tar.gz
Size 10.1 kB
Tags Source
SHA-256 checksum
How to use checksums
a66900c4b8169d3a22024cf1a168c91f853220c921e5309bb83f36428c5f0fca
BLAKE2b-256 checksum
How to use checksums
5d4ee9dc8492a6c7448bea0d4e5575b3a74817f226c9667d5ddc475f1ee71784
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 10, 2026.

Transparency log

Release files / refreshcss-0.6.0-py3-none-any.whl

Download URL refreshcss-0.6.0-py3-none-any.whl
Size 12.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
224546a9077647594b88d3d6f9895f9a813c09faa09a99f9c7c57f6ac532a24f
BLAKE2b-256 checksum
How to use checksums
5b2be4ad3c057eec181986f7d077b473c2dc923b718594f354916707676501b1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 10, 2026.

Transparency log

Security for refreshcss 0.6.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for refreshcss-0.6.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 10, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page