Last modified: Oct 14, 2026

How to Install whitenoise in Django

Static files disappear when you set DEBUG = False in Django. Your CSS, JavaScript, and images stop loading. The site looks broken in production.

WhiteNoise fixes this. It lets your Django application serve its own static files without nginx, Amazon S3, or any external service.

This guide walks through the full installation. You will install the package, configure the middleware, enable compression, and verify everything works.

What Is WhiteNoise?

WhiteNoise is a Python library that serves static files directly from your WSGI application. It makes your app self-contained and easier to deploy.

The library handles best practices automatically. It serves compressed content in gzip and Brotli formats. It sets far-future cache headers on files that never change.

WhiteNoise works with any WSGI-compatible app. Django gets extra auto-configuration, which makes setup very simple.

It is especially useful on platforms like Heroku, OpenShift, and other PaaS providers where adding a separate web server is not practical.

Prerequisites

Before installing WhiteNoise, check that your environment meets these requirements.

  • Python 3.8 or newer installed on your machine
  • Django 4.2 or higher in your project
  • pip available for package installation
  • An active virtual environment is recommended

Activate your virtual environment before installing. This keeps WhiteNoise isolated from other projects on your system.

You should also have a working Django project with static files configured. If you have never set up static files before, the Django documentation covers the basics.

Installing WhiteNoise with pip

The installation is a single command. Run this inside your activated virtual environment.

 pip install whitenoise 

This downloads the latest stable release from PyPI. WhiteNoise has no heavy dependencies, so installation is fast.

If you want Brotli compression support, install the extra. Brotli produces smaller files than gzip and is supported by all modern browsers.

 pip install "whitenoise[brotli]" 

For a requirements file, pin the version for reproducible builds.

 pip install whitenoise==6.7.0 

Pinning prevents surprise upgrades during deployment. You can check the current version on PyPI at any time.

Verifying the Installation

After installation, confirm the package is importable. Run this command in your terminal.

 python -c "import whitenoise; print(whitenoise.__version__)" 

You should see a version number printed.

 6.7.0 

The exact version may differ. What matters is that the import succeeds without errors.

If you see a "ModuleNotFoundError", pip installed the package for a different interpreter. Use python -m pip install whitenoise to ensure the correct target.

Adding WhiteNoise to Middleware

Open your project's settings.py file and add WhiteNoise to the MIDDLEWARE list. Placement matters.

The WhiteNoise middleware must come directly after Django's SecurityMiddleware and before all other middleware.

 # settings.py MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', # Add this line 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] 

The WhiteNoiseMiddleware class intercepts requests for static files before they reach the heavy Django logic. That makes static file delivery fast and efficient.

If you place it after other middleware, WhiteNoise still works. But you lose the performance benefit of early interception.

Configuring Static Files Settings

WhiteNoise needs Django to collect static files into one location. That location is defined by the STATIC_ROOT setting.

If you are starting a new project, add this to the bottom of your settings file.

 # settings.py import os STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') 

The STATIC_ROOT directory is where collectstatic puts every static file from your apps and static directories.

Make sure your templates use the {% static %} template tag instead of hardcoded URLs.

 {% load static %} Hi!Hi!

The template tag generates the correct URL whether you are in development or production. Hardcoded paths break when the URL prefix changes.

Running collectstatic

Before WhiteNoise can serve your files, you must run the collectstatic command. This copies every static file into STATIC_ROOT.

 python manage.py collectstatic 

You should see output showing how many files were copied.

 You have requested to collect static files at the destination location as specified in your settings. This will overwrite existing files! Are you sure you want to do this? Type 'yes' to continue, or 'no' to cancel: yes Copied 245 files to '/path/to/project/staticfiles' 

You need to run this command every time you deploy. Most PaaS providers run it automatically during the build process.

If collectstatic fails, check that STATIC_ROOT points to a valid directory. It should not be inside STATICFILES_DIRS.

Enabling Compression and Caching

The basic setup serves static files. But you should enable compression and caching for the best performance.

WhiteNoise provides a storage backend that compresses files and adds unique hashes to their names. Hashed files can be cached forever.

 # settings.py STORAGES = { "default": { "BACKEND": "django.core.files.storage.FileSystemStorage", }, "staticfiles": { "BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage", }, } 

The CompressedManifestStaticFilesStorage class combines compression with Django's manifest storage. It creates gzip and Brotli versions of each file.

Every file gets a content hash in its name. For example, style.css becomes style.abc123.css. The hash changes when the file changes, so browsers always get the right version.

If you want compression without the manifest hashing, use the alternative backend.

 "BACKEND": "whitenoise.storage.CompressedStaticFilesStorage" 

This compresses files but keeps the original names. It is useful when other tools depend on exact filenames.

Verifying That It Works

You can confirm WhiteNoise is working by running your app locally with DEBUG = False.

First, run collectstatic to make sure files are in place.

 python manage.py collectstatic --noinput 

Then set DEBUG = False in your settings file and start the development server.

 python manage.py runserver 

Open your site in a browser. Static files should load normally, just as they would in production.

You can also check the response headers for a static file. WhiteNoise adds cache headers automatically.

 Cache-Control: max-age=315360000, public, immutable Content-Encoding: gzip 

The immutable directive tells browsers never to revalidate the file. Combined with the content hash, this is safe and fast.

Common Installation Problems

Problem: "No module named 'whitenoise'"

The package is not installed for the active Python interpreter. Reinstall with python -m pip install whitenoise to target the correct environment.

Problem: Static files still return 404 with DEBUG=False

Check three things. First, whitenoise.middleware.WhiteNoiseMiddleware must be in MIDDLEWARE. Second, collectstatic must have run successfully. Third, STATIC_ROOT must point to the directory that collectstatic filled.

Problem: "ValueError: Missing staticfiles manifest entry"

This means a template references a static file that does not exist. Use Django's findstatic command to see where it looks.

 python manage.py findstatic --verbosity 2 missing-file.css 

The output lists every directory Django searches. If the file is genuinely missing, fix the template reference. If you want Django to ignore missing files, set WHITENOISE_MANIFEST_STRICT = False in settings.

Problem: "ValueError: The file 'style.css' could not be found"

This error often comes from CSS files that reference images or fonts that do not exist. Django tries to rewrite those references and fails when the target is missing. Check your CSS for broken url() paths.

Problem: Tests run slow with WhiteNoise

WhiteNoise scans all static files at startup. During test runs, apps start and stop frequently, which makes this scan expensive. Set WHITENOISE_AUTOREFRESH = True in your test settings to skip the scan.

Problem: collectstatic fails with a BrokenPipeError

This is a rare OS-level issue with the file copy operation. Retry the command. If it persists, check disk space and file permissions on STATIC_ROOT.

Problem: Compressed files not created

If you installed without the Brotli extra, only gzip files are created. Install whitenoise[brotli] to enable Brotli compression.

Best Practices

Pin your version. Add whitenoise==6.7.0 to your requirements file for consistent behavior across environments.

Always run collectstatic before deploy. Most deployment pipelines do this automatically. If yours does not, add it as a build step.

Use the manifest storage backend. The hash-based filenames enable aggressive caching without stale file risks.

Keep node_modules out of STATIC_ROOT. A large node_modules directory can contain thousands of files and slow down startup dramatically.

Test with DEBUG=False locally. Development mode hides static file problems. A quick local test with DEBUG off catches issues before they reach production.

Use a CDN for high-traffic sites. WhiteNoise sends proper cache headers, so a CDN can cache your static files and serve them without touching your app.

If your project also uses tagging or filtering, those features do not interfere with WhiteNoise. The approach to adding tags to Django models with django-taggit runs at the database layer and has no effect on static file serving.

Likewise, authentication systems are independent. The process of setting up social login with django-allauth touches templates and middleware but does not conflict with WhiteNoise configuration.

Conclusion

Installing WhiteNoise in Django takes three steps. Run pip install whitenoise, add the middleware, and configure the storage backend.

Then run collectstatic and test with DEBUG = False locally. Your static files now serve reliably in production without nginx or S3.

The library handles compression, caching, and content hashing for you. Those are the same optimizations you would otherwise configure by hand in a web server.

When you are ready to deploy, review how to deploy a Django app with Fabric to automate the release and ensure collectstatic runs on every deployment.

With WhiteNoise in place, your Django app is self-contained and portable. That simplicity makes deployment easier and keeps your static files fast.