changelogs/0.4.x.md
This release adds first-class support for Python projects that are not designed as Python packages (e.g., web applications, data science projects, etc.).
In doing so, it includes some breaking changes around uv's handling of projects. Previously, uv
required that all projects could be built into distributable Python packages, and installed them
into the virtual environment. Projects created by uv init always included a [build-system]
definition and existing projects that did not define a [build-system] would use the legacy
setuptools build backend by default.
Most users are not developing libraries that need to be packaged and published to PyPI. Instead,
they're building applications using web frameworks, or running collections of Python scripts in the
project's root directory. In these cases, requiring a [build-system] was confusing and
error-prone. In this release, uv changes the default behavior to orient around these common use
cases.
In summary, the major changes are:
[build-system].
package = true in the [tool.uv] section of
your pyproject.toml.uv init no longer creates a src/ directory or defines a [build-system] by default.
uv init --lib or uv init --app --package.[project] definitions in virtual workspace roots.
[project] section to be omitted.[build-system], by setting
package = false in the [tool.uv] section of your pyproject.toml.See the latest documentation on build systems in projects for more details.
--app and --lib options to uv init (#6689)virtual source label in lockfile for non-packaged dependencies
(#6728)--hashes are omitted
(#6731){package}@{version} in uv tool install
(#6762).egg-info from mutable sources
(#6714)tool.uv.sources
(#6706)--frozen
(#6737)uv python list
(#6740)uv init to create the pyproject.toml
(#6752)uv export --format requirements-txt (#6778)@ references in uv tool install --from
(#6842)requires-python
(#6824)--no-workspace in uv init failures
(#6815)PATH (#6829)uv init --no-project alias (#6837)requires-python
(#6813)uv add and uv remove
(#6787)hello.py to pass ruff format
(#6811)pyproject.toml in uv add operations
(#6388)))[pip] section from configuration file docs
(#6814)project.urls in pyproject.toml (#6844)is_disjoint check for supported environments
(#6902)uv cache clean ${package}
(#6915)--isolated workspace
(#6885)--verbose is provided
(#6903)uv sync --frozen --package without copying member pyproject.toml
(#6943)uv add
(#6939)UV_PROJECT_ENVIRONMENT
(#6834)VIRTUAL_ENV is set but will not be respected in project commands
(#6864)--no-hashes to uv export (#6954).python-version in uv init (#6869)file:// URLs for UV_PYTHON_INSTALL_MIRROR
(#6950)uv python list --all-versions
(#6917)requires-python marker simplifications
(#6268)UV_PROJECT_ENVIRONMENT
(#6987)file:// scheme in Python installation mirrors
(#6984)docker.md (#6921)uv build (#6895)--package support to uv build (#6990)uv build (#6912)uv build --wheel from source distributions
(#6898)uv add
(#7023)uv tool run and uv run
(#6994)pyproject.toml modifications on Ctrl-C
(#7024)pyproject.toml changes on all errors
(#7022)__future__.annotations import in _virtualenv.py
(#6996)uv build (#6991)extra and all-extras in uv sync help
(#7013)project.scripts (#7010)uv.toml (#6986)-slim variants
(#7041)--build-constraint in uv build (#7085)--require-hashes and --verify-hashes to uv build
(#7094)--show-version-specifiers to uv tool list
(#7050)uv tool upgrade and uninstall
(#7037)uv python list (#6918)--no-build and --no-binary in uv sync et al
(#7100)ENTRYPOINT and CMD for inherited images
(#7054)setup-uv action (#7056).python-version file (#7051)--no-emit-project and friends to uv export
(#7110)--output-file to uv export (#7109)uv cache prune
(#7112)--no-deps and pip sync
(#7127)uv python list
(#7131).python-version files
(#7140).dist-info names with dashes for post releases
(#7208)uv init (#7225).tgz the same as .tar.gz (#7201)uv venv to create a virtual environment
(#7188)--universal output
(#7209)sitecustomize.py (#7161)--source and --binary flags with correct --sdist and --wheel flags in
uv build (#7156)uv self update
(#7252)py.typed files during uv init --lib
(#7232)distutils deprecation
(#7239)uv run --no-sync (#7192pyproject.toml offsets on non-add edits
(#7262)--config-settings change
(#7139)uv export
(#7254)uv tool upgrade --all to continue on individual upgrade failure
(#7333)tool.uv.cache-keys
(#7268)__main__.py) support to uv run
(#7281)uv run (#7289)--token option to self update command (#7279)globwalk for cache-keys matching (#7337)--no-install options when constructing resolution
(#7277)py.typed files contents in uv init
(#7338)uv python list
(#7290)uv add --script (#7301)uv build --build-constraint flag
(#7330).whl sources as source distributions
(#7303)--no-editable support to uv sync and uv export
(#7371)--only-dev to uv sync and uv export
(#7367)uvx (#7388)uv export command in requirements.txt output
(#7374)uv cache prune --ci
(#7446)uv sync a package without build configuration
(#7420)--python option
(#7335).dist-info directories
(#7444)uv venv --seed environments
(#7410)tool.uv.sources contains duplicate package names
(#7383)--branch et al when resolving unnamed URLs in uv add
(#7447)dev-dependencies in --no-sources invocations
(#7408)--system is used
(#7440)--no-sources in PEP 723 scripts (#7409)pyproject.toml credentials from user-provided requirements
(#7474)uv export (#7378)project.name (#6803)project.name error for workspaces
(#7399)socks support (#7503)PATH
(#7470)CACHEDIR.TAG file exists but cannot be written to
(#7550)UV_LINK_MODE to Docker caching example (#7510)uvx --generate-shell-completion
(#7511)uv add
(#7597)ghcr.io
(#7568)--no-sources is provided
(#7599)sys.base_prefix collision in interpreter identity check during tool installs
(#7596)uv cache prune robust to unreadable rkyv entries
(#7561)- to _ in packaged applications document
(#7571)uv publish (#7475)--project argument to run a command from a project directory
(#7603)uv publish (#7548)--with requirements
(#7627)--directory option (#7653)--unsafe-best-match
(#7645)requires-python range changes
(#7624)link-mode=clone for directories on Linux
(#7620)uv build --all to build all packages in a workspace
(#7724)uv init --script (#7565)uv tool upgrade --python)
(#7605)uv init (#5476)--quiet flag in uv build (#7674)uvx
(#7641)uv build and uv publish to features overview
(#7716)uv lock --upgrade-package retains locked versions
(#7694)tool.uv.sources
(#7745).gitignore file to uv build output directory
(#7835)PAGER env var when paging in uv help command
(#5511)uv run -m foo to run a module (#7754)uv build in workspaces
(#7813)uv init --package command to match project name
(#7670)uv add dotenv (#7799)tool.uv.sources deserialization failures
(#7823)serde-untagged to improve some untagged enum error messages
(#7822)dotenv errors, rather than in uv add
(#7825)UV_NO_SYNC environment variable (#7752)git+ prefix in tool.uv.sources (#7847)--no-binary
(#7772)uv tree --invert for platform dependencies
(#7808)uv add (#7766)tool.uv.environments for legacy virtual workspace roots
(#7824)FlatDistributions public (#7833)uv publish instead of twine in docs (#7837)projects.md (#7784)uv add (#7864)requires-python
(#7904)--script to uv run to treat an input as PEP 723 regardless of extension
(#7739)UV_FIND_LINKS environment variable for --find-links
(#7912)UV_PYTHON environment variable
(#7878)py3x-none tags in newer than Python 3.x
(#7867)dev section (#7943)cp2 wheels in resolution (#7902)gnueabi libc variants in Python version requests
(#7975)uv tree --package foo
(#7885)uv python install
(#8010)uv publish failures
(#7872)uv run
(#7687)authors field during uv init (#7756)uvx to uv tool run short help
(#7695)uv tree --no-dev (#8109)uv run - (#8111)pip install --exact (#8044)uv export --no-header (#8096)https://) scripts in uv run
(#6375)uv run --with
(#7909)UV_INSECURE_HOST (#8052)uv python CLI
(#8020)pyvenv.cfg file exists
(#8012)requires-python bounds
(#8140)netrc crate to latest commit (#8021)uv python pin 3.13t failure when parsing version for project requires check
(#8056)requires-python
(#7897)uv lock and uv sync
(#8091)git config --get for author information for improved backwards compatibility
(#8101)UV_FIND_LINKS
(#8061)--relocatable entrypoints robust to symlinking
(#8079)--with-requirements in uvx error hint (#8112)uvx installation in Docker examples (#8179)--reinstall with --exclude-newer to ensure downgrades
(#6721)[tool.uv.sources] in build requirements
(#7172)uv publish error message for missing usernames
(#8045)uv publish (#8158)uv publish (#8204)which git (#8224)uv pip install --exact
(#8219)--prerelease=allow during build requirement resolution errors
(#8192)python-build-standalone releases (#8216)uv build builds in the source distribution bucket
(#8220)This release introduces a revamped system for defining package indexes, as an alternative to the
existing pip-style --index-url and --extra-index-url configuration options.
You can now define named indexes in your pyproject.toml file using the [[tool.uv.index]] table:
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
Packages can be pinned to a specific index via tool.uv.sources, to ensure that a given package is
installed from the correct index. For example, to ensure that torch is always installed from the
pytorch index:
[tool.uv.sources]
torch = { index = "pytorch" }
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
Indexes can also be marked as explicit = true to prevent packages from being installed from that
index unless explicitly pinned. For example, to ensure that torch is installed from the pytorch
index, but all other packages are installed from the default index:
[tool.uv.sources]
torch = { index = "pytorch" }
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
explicit = true
To define an additional index outside a pyproject.toml file, use the --index command-line
argument (or the UV_INDEX environment variable); to replace the default index (PyPI), use the
--default-index command-line argument (or UV_DEFAULT_INDEX).
These changes are entirely backwards-compatible with the deprecated --index-url and
--extra-index-url options, which continue to work as before.
See the Index documentation for more.
uv add --index or --default-index
(#7746)tool.uv.sources
(#7769)uv add (#7747)--index and --default-index values in tool.uv.sources
(#7910)requires-python warnings (#8240)Forbidden (403) or Unauthorized (401)
(#8264)cargo-dist version (includes new installer features)
(#8270)requires-python is implicitly 0
(#7959)--emit-index-url
(#8226)uv-pep508
(#8282)uv build sources (#8237)--index-url docs
(#8267)UV_INDEX_ rather than UV_HTTP_BASIC_ as documented
(#8306)uv pip show --files (#8369)tool.uv.sources table if it is empty (#8365)UV_FROZEN and UV_LOCKED (#8340)uv add and uv remove
(#8359)uv.lock (#8333)[tool.uv.sources] if it is no long being referenced
(#8366)uv pip list and uv tree to print to stdout regardless of --quiet flag
(#8392)self update invocations
(#8337).netrc parsing errors (#8364)macos-x86_64 on macos-14 runners
(#8327)uv python install --reinstall
(#8487)uv.toml configuration
(#7851)requires-python narrowing with upper bounds
(#8403)[[tool.uv.index]] entries when credentials are provided
(#8502)uv add comment handling for empty arrays
(#8504)--allow-insecure-host in uv publish
(#8440)--package includes in uv tree
(#8507)uv python install
(#8485)[tool.uv.dependency-metadata]
(#8484)cache-keys typo in tags = true (#8422)--from command when executable is available for uvx
(#8473)--with-editable in uv tool install
(#8472)This release includes support for the [dependency-groups] table as recently standardized in
PEP 735. The table allows for declaration of optional
dependency groups that are not published as part of the package metadata, unlike
[project.optional-dependencies]. There are new --group, --only-group, and --no-group options
throughout the uv interface.
Previously, uv used a single tool.uv.dev-dependencies list for declaration of development
dependencies. Now, uv supports declaring development dependencies in a standardized format and
allows splitting development dependencies into multiple groups.
For compatibility, and to simplify usage for people that do not need multiple groups, uv
special-cases the group named dev. The dev group is equivalent to tool.uv.dev-dependencies.
The contents of tool.uv.dev-dependencies will merged into the dev group in uv's resolver. The
--dev, --only-dev, and --no-dev flags remain as aliases for the corresponding --group
options. Support for tool.uv.dev-dependencies remains in this release, but will display warnings
in a future release.
uv syncs the dev group by default — this matches the existing behavior for
tool.uv.dev-dependencies. The default groups can be changed with the tool.uv.default-groups
setting.
Thank you to Stephen Rosen who authored PEP 735.
--dry-run mode in uv lock (#7783)uv tree
(#8532)lto over debug free-threaded managed Python builds
(#8515)tool.uv.sources to the "Settings" reference
(#8543)uv build and uv publish in the landing pages
(#8542)[tool.uv] header in TOML examples
(#8545).netrc environment variable and path
(#8511).netrc typo in authentication docs (#8521)--publish-url to avoid duplication.
(#8561)--strict flag (#8513)+freethreaded
(#8645)return from Maturin project template
(#8604)uv export
(#8638)uv tree (#8564)uv init to imply --package when using --build-backend
(#8593)dev-dependencies and requires-dev for lockfile compatibility
(#8599)requires-python requirement for dependencies
(#8619)--cache-dir (#8627)uv python install
(#8684)riscv64 to supported Python platform tags
(#8660)uv pip tree (#8689)uv export
(#8659)uv init --virtual to imply --no-package
(#8595)uv python install (Unix only)
(#8458)requires-python range
(#8688)Requires-Python
(#8679).env and custom env files in uv run
(#8811)--all-packages in uv run, uv sync, and uv export
(#8742,
#8741,
#8739)--frozen with --all-packages in uv sync and uv export
(#8760)--check-url to uv publish to check for existing distributions during upload
(#8531)--check-url when --skip-existing is used
(#8803)requires-python for source distributions with static metadata
(#8768)--python-preference system
(#8808)--group defined in non-root workspace member
(#8734)uv python uninstall
(#8725)python_version < '0' could appear in a final resolution
(#8759)add httpx example with real git branch (#8756)projects.md (#8772)README (#8720)