setuptools vs. distutils why is distutils still a thing?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
distutils was the original standard-library packaging toolkit for Python, while setuptools grew into the richer tool most projects actually use. The confusing part is that distutils is historically important, still appears in old code and documentation, but is no longer the tool you should choose for new packaging work.
What distutils Was For
distutils provided the basic building blocks for packaging and installing Python projects. It supported simple source distributions and extension-module builds, but it was intentionally minimal.
That minimalism became a problem as packaging needs grew. Modern packaging expects dependency metadata, entry points, wheels, build isolation, and better interoperability with package indexes and installers. distutils never became the right place for that ecosystem to evolve.
Why setuptools Took Over
setuptools started as an extension on top of the older model and became the de facto standard for Python package building for many years. It added capabilities such as:
- dependency declaration
- console script entry points
- wheel-oriented packaging workflows
- richer extension hooks
A small modern example uses pyproject.toml and setuptools as the build backend:
This is the packaging direction most current Python projects should follow.
So Why Do People Still Mention distutils
There are three main reasons.
First, a huge amount of legacy packaging material was written around setup.py and distutils. Older blog posts, tutorials, and internal enterprise packages still refer to it.
Second, for years setuptools itself preserved compatibility with distutils concepts and interfaces, so many developers interacted with the old vocabulary even when they were effectively using newer tooling.
Third, transition in packaging ecosystems is slow. Build tools, CI jobs, downstream Linux packaging, and extension-module workflows often lag behind best practice.
The Current State
Python formally deprecated distutils and removed it from the standard library in Python 3.12. That is the key fact that clears up the confusion: distutils still matters historically, but it is not a future-facing packaging choice.
You may still see imports that appear to use distutils, especially in old setup scripts or compatibility code. In many real projects, those references exist because the code has not been modernized yet, not because distutils remains the preferred approach.
Some tooling also preserved pieces of the old behavior for compatibility, which makes the ecosystem look more alive than it really is.
What You Should Use Instead
For new packages:
- use
pyproject.toml - choose a supported build backend such as
setuptools,hatchling, orflit - build wheels and source distributions through standard frontend tools
Example:
That command uses the declared backend from pyproject.toml and avoids relying on legacy packaging entry points.
If you maintain an older setup.py project, modernizing does not have to be all-or-nothing. Start by moving build metadata into pyproject.toml, then reduce or remove direct distutils usage as you touch the package.
Common Pitfalls
The biggest mistake is treating distutils as merely an older equivalent of setuptools. It is not just older; it is also deprecated and removed from the stdlib in current Python.
Another common issue is copying a legacy setup.py example without checking whether it still reflects modern packaging practice.
Teams also sometimes assume packaging means setuptools only. In reality, modern Python packaging is built around standardized metadata and backend interfaces, so you have choices.
Finally, do not confuse installation tooling with build backend choice. pip, build, and the backend each play different roles.
Summary
- '
distutilswas Python’s original packaging toolkit, but it is now legacy technology.' - '
setuptoolsbecame the dominant successor because it solved practical packaging needs.' - Python removed
distutilsfrom the standard library in Python 3.12. - New projects should use
pyproject.tomlwith a supported build backend. - You still see
distutilsmainly because old code and compatibility layers linger.
Related reading
- SFTP in Python? platform independent
- Shell Script Execute a python program from within a shell script
- Shortest Sudoku Solver in Python - How does it work?
- Should conda, or conda-forge be used for Python environments?
- Should I be adding the Django migration files in the .gitignore file?
- Should I have separate containers for Flask, uWSGI, and nginx?
- Should I put
- Should I put shebang in Python scripts, and what form should it take?
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.