# Source to installation
## Build an sdist
- Inputs
- Source
- Build backend
- Dependencies
- Environment
- Output
- sdist
Go from source to an sdist.
## Build a wheel
- Inputs
- sdist
- Build backend
- Dependencies
- Environment
- Output
- wheel
Use an sdist to build a wheel.
## Upload to PyPI
- Inputs
- sdist
- wheels
- Access token
- Environment
- Metadata
- Output
- N/A
## Download from an index
- Inputs
- Installer
- Metadata
- File names
- Environment
- Output
- File to install
Resolve what to download and download it.
## Install
- Inputs
- Installer
- wheel
- sdist
- Build backend
- Dependencies
- Environment
- Output
- Files on disk
Take what you downloaded and install it.
# Mitigations
- [[Reproducible builds]]
- [Better defaults](https://nesbitt.io/2026/03/31/npms-defaults-are-bad.html)
- Opt into using anything other than wheels
- Cooldown
- Implicitly update lock files
- Lock files
- Cooldown
- Attestations
- Trusted Publishing
- Staged uploads w/ 2FA
- External hash verification
- CVEs