Well, to start, it is not an alternative to
pip. It's built on top of
pip and exclusively deals with applications.
pip is more of a development tool, while
pipx is aimed at end-users (who may also be developers).
As a final note before turning to more substantive topics, an application does not need to be large and complicated to be valuable. In this case, the main value proposition is ergonomics/ease-of-use. A secondary benefit is that it provides an abstraction layer. You don't need to know how it works to use it, and that means how it works can change without changing how you use it.
So, why use this instead of
pip provides no isolation. This makes it a headache to deal with different libraries and applications that have dependencies on different versions of the same libraries. It also means installing or upgrading a package might unwittingly break something else. Common practice is to use tools like virtualenv, Conda, venv, and others to get isolation, but these are much more oriented to developers. Using these together to run an application with isolation would require several commands and manually keeping track of various "environments". This "environment" concept is great for developers who want to install several libraries within a single environment, but for applications there's (usually) no reason to have different applications "see" the same environment. This "environment" concept just complicates the flow that
pipx is aiming for.
Okay, why use this instead of a system package manager?
Mainly, most package managers need someone else to package things for you. If they haven't, then oh well. Package managers also usually don't provide isolation and make it very difficult to have multiple versions of the same "package". Their ethos is usually provide a "known good" selection of packages, but this makes them slow to change and often incomplete and out-of-date. A small but real annoyance is often system packages have slightly different names than the corresponding Python packages meaning you need an extra "look up the corresponding system package" step to installing something you see on PyPI or GitHub.
- Easy Python application installation with no need to worry about conflicting versions of things.
- Addition of such applications to the
PATH allowing them to be used seamlessly.
- Easy uninstallation and upgrade.
- Use of the PyPI namespace.
- Ephemeral environments for one-off executions.
- For developers of Python applications, less need to deal with unknown mixtures of libraries.
I refer you to How pipx works, but, as a quick summary as of August 2023, it does the "obvious" thing. It installs each application in its own virtual environment via
venv. It then adds symbolic links to
~/.local/bin. It is very slightly cleverer than that and will reuse a virtual environment for the packaging tools themselves.
This does mean you will have duplication of library code. This is a common problem with many language-specific package managers, not just Python's. It is a real problem as it is very easy to have many gigabytes of wasted space in duplicated dependencies. There's also a lot of time wasted installing duplicate dependencies. The best solution I've seen to this problem is to adopt Nix's approach. The key to this approach is to allow not just installing different versions of the same library side-by-side, but also the same library version with different dependencies side-by-side. This allows a single shared environment where dependencies are never duplicated, though you can definitely have multiple very similar libraries installed. This requires all dependencies to be easily identifiable and builds to be deterministic which are properties that are hard to ensure in the Python ecosystem. The only language-specific package manager I'm aware of that uses this approach is Haskell's
As I mentioned before,
pipx could, in theory, transparently switch to such an approach if it ever became available.
Why not use
There are plenty of use-cases
pipx is not aimed at where it would be unnecessary or irrelevant, e.g. system images in an immutable infrastructure setup. For the use-case it is targeted at, i.e. personal machines, the only good options are, if possible, restrict yourself to "standard" system packages, or use
pipx. The other options are to manually do what
pipx does or forgo isolation and enter dependency hell.