CLI tool
pypa/hatch avatar
pypa/hatch

Hatch pulls in uv and virtualenv, and two release trains

Modern, extensible Python project management

7,249 stars492 forksPythonMIT

At a glance

What is it?
Hatch bundles build, environments, tests, publishing, and versioning into one extensible CLI. Its own metadata is the honest spec: a heavy toolchain, two release trains, a version read from git tags, and no documented install command.
Who is it for?
Choose Hatch if you want one extensible CLI that covers environments, tests, static analysis, publishing, and versioning, and if you are willing to let uv and virtualenv into your build image unconditionally. Check the classifier list against the interpreters your matrix actually runs, and pin hatchling separately if your builds depend on backend behaviour.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • pypa/hatch7,249 ★ · +13
Star history
Repository2026-09-232026-11-14
pypa/hatch7.2k7.2k

13 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The README hands you PyPI links instead of an install command

The README contains nothing you can paste into a shell. Its badge row links the hatch package on PyPI, the GitHub releases page, and the documentation at hatch.pypa.io, and that is the entire installation story. The contract that actually binds your machine lives in the package metadata, and Hatch's own metadata is the cleanest available copy of it:

toml
[project]
name = "hatch"
description = "Modern, extensible Python project management"
readme = "README.md"
license = "MIT"
license-files = ["LICENSE.txt"]
requires-python = ">=3.10"

Two consequences follow. Anything older than Python 3.10 is out, with no compatibility shim on offer. And the package name, readme file, license, and license file are all declared outright rather than inferred, so a packaging tool has nothing left to guess about.

Environment tooling is a hard dependency, not an extra

Hatch does not treat its environment layer as optional. Installing the CLI drags the whole toolchain in:

toml
dependencies = [
  "click>=8.0.6",
  "distro>=1.0.0; sys_platform == 'linux'",
  "hatchling>=1.27.0",
  "httpx2>=0.22.0",
  "hyperlink>=21.0.0",
  "keyring>=23.5.0",
  "packaging>=24.2",
  "pexpect~=4.8",
  "python-discovery>=1.1",
  "platformdirs>=2.5.0",
  "pyproject-hooks",
  "rich>=11.2.0",
  "shellingham>=1.4.0",
  "tomli-w>=1.0",
  "tomlkit>=0.11.1",
  "userpath~=1.7",
  "uv>=0.5.23",
  "virtualenv>=21",
  "backports.zstd>=1.0.0 ; python_version<'3.14'",
]

uv>=0.5.23 and virtualenv>=21 sit in the same list as click and rich, so there is no configuration in which you end up with Hatch and no resolver or virtual environment implementation on the path. python-discovery>=1.1 is in there too. Watch the bounding style: only pexpect~=4.8 and userpath~=1.7 carry upper limits, so nearly everything else floats. A pinned Hatch can therefore still resolve to different trees on different days, and any audit of a build image has to put uv and virtualenv in scope.

Two environment markers change the tree under your feet

Two lines in that dependency list carry environment markers, and they behave differently from each other.

backports.zstd>=1.0.0 is gated on python_version<'3.14', so a zstd backport gets installed for 3.10 through 3.13 and then vanishes on 3.14. distro>=1.0.0 is gated on sys_platform == 'linux', so on macOS or Windows nothing is installed in its place. Same package, same version number, different dependency set depending on the interpreter and the machine. If your matrix runs 3.10 and 3.14 side by side, those are not the same environment, and any claim that a Hatch install is reproducible has to be stated per interpreter version and per platform. The classifier list carries Operating System :: OS Independent, but independence of the operating system is not the same thing as an identical dependency list across operating systems.

Hatch builds itself with Hatchling, and two release trains move at once

Hatch delegates its own build to Hatchling and gets its version from git:

toml
[build-system]
requires = ["hatchling>=1.27", "hatch-vcs>=0.3.0"]
build-backend = "hatchling.build"

hatch-vcs derives the version, and pyproject.toml confirms the intent by declaring dynamic = ["version"] rather than writing a number. Nothing in that file tells you which version you are holding. The tag does.

The effect shows up in the release list. Hatchling 1.32.4 shipped on 2026-09-20 and 1.33.0 on 2026-10-28, while Hatch 1.18.2 shipped on 2026-10-28, twelve minutes after Hatchling 1.33.0. The backend moves faster than the frontend, and the frontend only asks for hatchling>=1.27.0. Pinning hatch alone therefore does not pin the backend, and a behaviour change in the packaging backend can reach you without you changing the tool you upgraded.

The speed claim points at a workflow file, not at numbers

The README advertises a CLI around 2 to 3 times faster than equivalent tools, and the link behind that phrase points at a GitHub Actions workflow named cli.yml inside this repository rather than at a published table of measurements. No command, no machine, no interpreter version is given. The repository root hints at what is being measured rather than what was measured: ruff.toml and ruff_defaults.toml for linting, pyrefly.toml for type checking, and a badge row that also links mypy, so two type checkers are configured side by side. Read the ratio as something the maintainers track in a workflow and a reader cannot check. If command latency matters to your CI budget, time it on your own repository instead of sizing a pipeline from that line.

Docs, static builds, and the backend share one branch

The repository root shows the shape of the thing: hatch.toml for the manager's own configuration, mkdocs.yml for the documentation, pyoxidizer.bzl for a static build path, plus backend/, src/, release/, scripts/, docs/, tests/, a SECURITY.md, and a .linkcheckerrc for validating outbound links. The documentation is built with MkDocs and hosted on GitHub Pages, with separate workflows for development builds and released builds, and the default branch is master. Everything lands on that one branch, so the docs, the CLI, and the build backend move together. The last push to master was 2026-10-28, the same day Hatch 1.18.2 and Hatchling 1.33.0 were released. The project URLs in pyproject.toml include a History link under hatch.pypa.io/dev/.

The word hatch on its own leads somewhere else

The bare word is a poor handle for this tool. The project's entry points are the homepage hatch.pypa.io/latest/, the PyPI project page, and the GitHub releases page. Go in through the documentation URL or the package name, and expect to spell out the difference when you hand the tool to someone who heard the name and pictured something else entirely.

Editorial conclusion

Choose Hatch if you want one extensible CLI that covers environments, tests, static analysis, publishing, and versioning, and if you are willing to let uv and virtualenv into your build image unconditionally. Check the classifier list against the interpreters your matrix actually runs, and pin hatchling separately if your builds depend on backend behaviour. Skip it if your environment tooling is already fixed by policy, or if a dependency set that changes between Python 3.13 and 3.14 is a problem for you. Verify the install path yourself first, since the README gives no command.

Frequently asked questions

Does Hatch need uv or virtualenv installed separately?

No separate step is described anywhere in the README. uv>=0.5.23 and virtualenv>=21 both appear in the dependency list of the hatch package itself, so installing the CLI brings a resolver and a virtual environment implementation with it. The README points at the PyPI project page and the GitHub releases page for obtaining the tool.

Which Python versions does Hatch support?

requires-python is >=3.10, and the classifiers name Python 3.10, 3.11, 3.12, 3.13, 3.14, and 3.15 on both the CPython and PyPy implementations. One dependency, backports.zstd>=1.0.0, is gated on python_version<'3.14', so it is installed below 3.14 and not on 3.14.

How does Hatch determine its own version number?

The build requirements pair hatchling with hatch-vcs>=0.3.0, and the project table declares dynamic = ["version"] instead of a literal. The version is derived from the repository history rather than written into pyproject.toml, so the file itself never tells you which build you have.

Does Hatchling carry the same version number as Hatch?

They are separate packages on separate tracks. hatchling-v1.33.0 was released on 2026-10-28 and hatchling-v1.32.4 on 2026-09-20, while hatch-v1.18.2 came out on 2026-10-28. The hatch package requires hatchling>=1.27.0, so the frontend tracks a range of the backend rather than a matching release.

What does Hatch manage besides building and publishing?

The feature list names environment management with custom scripts and UV, Python distribution management, test execution, static analysis, a built-in Python script runner, version management, and project generation from templates. None of those commands appear in the README, which stays at the level of a linked page per capability.

Official sources

  1. License: MIT
  2. Project website
  3. pypa/hatch on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/pypa-hatch.svg)](https://hysenlabs.com/projects/pypa-hatch)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/pypa-hatch.svg)](https://hysenlabs.com/projects/pypa-hatch)

Was this useful?