You can download pip packages for offline use by telling pip to "build" them without installing them, which effectively just downloads and unpacks them into a local directory.

Let’s see it in action. Imagine you need requests and numpy for an air-gapped machine. You’d run this on a machine with internet access:

pip download --dest /path/to/offline-packages requests numpy

This command tells pip to go out to PyPI, find the latest compatible versions of requests and numpy (and any dependencies they might have, like charset-normalizer, idna, urllib3 for requests, or pybind11, numpy itself for numpy), and download their distribution archives (usually .tar.gz or .whl files) into the /path/to/offline-packages directory.

Once that’s done, you can copy that entire directory to your offline machine. On the offline machine, you can then install these packages without an internet connection using the --no-index and --find-links flags:

pip install --no-index --find-links=/path/to/offline-packages requests numpy

Here’s the breakdown of what’s happening:

  • pip download: This is the core command. It tells pip to fetch package archives.
  • --dest /path/to/offline-packages: This specifies where the downloaded archives should be placed. You can use any directory path you like.
  • requests numpy: These are the packages you want to download. Pip will automatically resolve and download their dependencies.
  • --no-index: This crucial flag tells pip not to look for packages on PyPI or any other remote index. It restricts pip to only consider local sources.
  • --find-links=/path/to/offline-packages: This tells pip where to find the local package archives it needs for installation. It points pip to the directory where you previously ran pip download.

This process is invaluable for several scenarios:

  • Air-gapped environments: Machines that have no internet connectivity for security reasons.
  • Reproducible builds: Ensuring that your project always installs the exact same versions of dependencies, even if PyPI changes or a package is removed.
  • Faster deployments: If you have a local network mirror or are deploying to many machines, downloading once and distributing locally is much faster than each machine downloading from PyPI.
  • Specific Python versions/platforms: You can use pip download on a machine that matches your target environment (e.g., same OS, same Python version) to ensure you’re getting compatible wheels, or you can use flags like --platform, --python-version, and --implementation on the download machine to fetch packages for a different target.

The mental model here is that pip download is essentially creating a private, local PyPI repository for your chosen packages. When you later use pip install with --find-links and --no-index, you’re telling pip to treat that directory as the sole source of truth for your packages, bypassing the internet entirely.

You can also specify versions during download. For example, to get exactly requests==2.28.1:

pip download --dest /path/to/offline-packages requests==2.28.1

This is how you build a robust offline installation strategy.

When you need to update packages in your offline repository, you simply run pip download again with the new versions you want, and then copy the updated files over.

Want structured learning?

Take the full Pip course →