uv/docs/concepts/projects/init.md
Zanie Blue 00d3aa3780
Some checks failed
CI / lint (push) Has been cancelled
zizmor / Run zizmor (push) Has been cancelled
CI / Determine changes (push) Has been cancelled
CI / cargo shear (push) Has been cancelled
CI / typos (push) Has been cancelled
CI / mkdocs (push) Has been cancelled
CI / ecosystem test | pydantic/pydantic-core (push) Has been cancelled
CI / integration test | deadsnakes python3.9 on ubuntu (push) Has been cancelled
CI / integration test | pypy on windows (push) Has been cancelled
CI / check system | python on macos aarch64 (push) Has been cancelled
CI / check system | conda3.8 on linux x86-64 (push) Has been cancelled
CI / check system | conda3.11 on windows x86-64 (push) Has been cancelled
CI / check system | conda3.8 on windows x86-64 (push) Has been cancelled
CI / cargo clippy | ubuntu (push) Has been cancelled
CI / cargo clippy | windows (push) Has been cancelled
CI / cargo dev generate-all (push) Has been cancelled
CI / cargo test | ubuntu (push) Has been cancelled
CI / cargo test | macos (push) Has been cancelled
CI / cargo test | windows (push) Has been cancelled
CI / check windows trampoline | aarch64 (push) Has been cancelled
CI / check windows trampoline | i686 (push) Has been cancelled
CI / check windows trampoline | x86_64 (push) Has been cancelled
CI / test windows trampoline | aarch64 (push) Has been cancelled
CI / test windows trampoline | i686 (push) Has been cancelled
CI / test windows trampoline | x86_64 (push) Has been cancelled
CI / build binary | linux libc (push) Has been cancelled
CI / build binary | linux aarch64 (push) Has been cancelled
CI / build binary | linux musl (push) Has been cancelled
CI / build binary | freebsd (push) Has been cancelled
CI / build binary | macos aarch64 (push) Has been cancelled
CI / build binary | macos x86_64 (push) Has been cancelled
CI / build binary | windows x86_64 (push) Has been cancelled
CI / build binary | windows aarch64 (push) Has been cancelled
CI / build binary | msrv (push) Has been cancelled
CI / ecosystem test | prefecthq/prefect (push) Has been cancelled
CI / ecosystem test | pallets/flask (push) Has been cancelled
CI / smoke test | linux (push) Has been cancelled
CI / smoke test | linux aarch64 (push) Has been cancelled
CI / check system | alpine (push) Has been cancelled
CI / smoke test | macos (push) Has been cancelled
CI / smoke test | windows x86_64 (push) Has been cancelled
CI / smoke test | windows aarch64 (push) Has been cancelled
CI / integration test | activate nushell venv (push) Has been cancelled
CI / integration test | conda on ubuntu (push) Has been cancelled
CI / integration test | free-threaded on windows (push) Has been cancelled
CI / integration test | aarch64 windows implicit (push) Has been cancelled
CI / integration test | aarch64 windows explicit (push) Has been cancelled
CI / integration test | pypy on ubuntu (push) Has been cancelled
CI / integration test | graalpy on ubuntu (push) Has been cancelled
CI / integration test | graalpy on windows (push) Has been cancelled
CI / integration test | pyodide on ubuntu (push) Has been cancelled
CI / integration test | github actions (push) Has been cancelled
CI / integration test | free-threaded python on github actions (push) Has been cancelled
CI / integration test | pyenv on wsl x86-64 (push) Has been cancelled
CI / integration test | determine publish changes (push) Has been cancelled
CI / integration test | registries (push) Has been cancelled
CI / integration test | uv publish (push) Has been cancelled
CI / integration test | uv_build (push) Has been cancelled
CI / check cache | ubuntu (push) Has been cancelled
CI / check cache | macos aarch64 (push) Has been cancelled
CI / check system | python on debian (push) Has been cancelled
CI / check system | python on fedora (push) Has been cancelled
CI / check system | python on ubuntu (push) Has been cancelled
CI / check system | python on rocky linux 8 (push) Has been cancelled
CI / check system | python on rocky linux 9 (push) Has been cancelled
CI / check system | graalpy on ubuntu (push) Has been cancelled
CI / check system | pypy on ubuntu (push) Has been cancelled
CI / check system | pyston (push) Has been cancelled
CI / check system | homebrew python on macos aarch64 (push) Has been cancelled
CI / check system | x86-64 python on macos aarch64 (push) Has been cancelled
CI / check system | python on macos x86-64 (push) Has been cancelled
CI / check system | python3.10 on windows x86-64 (push) Has been cancelled
CI / check system | python3.10 on windows x86 (push) Has been cancelled
CI / check system | python3.13 on windows x86-64 (push) Has been cancelled
CI / check system | x86-64 python3.13 on windows aarch64 (push) Has been cancelled
CI / check system | aarch64 python3.13 on windows aarch64 (push) Has been cancelled
CI / check system | windows registry (push) Has been cancelled
CI / check system | python3.12 via chocolatey (push) Has been cancelled
CI / check system | python3.9 via pyenv (push) Has been cancelled
CI / check system | python3.13 (push) Has been cancelled
CI / check system | conda3.11 on macos aarch64 (push) Has been cancelled
CI / check system | conda3.8 on macos aarch64 (push) Has been cancelled
CI / check system | conda3.11 on linux x86-64 (push) Has been cancelled
CI / check system | amazonlinux (push) Has been cancelled
CI / check system | embedded python3.10 on windows x86-64 (push) Has been cancelled
CI / benchmarks | walltime aarch64 linux (push) Has been cancelled
CI / benchmarks | instrumented (push) Has been cancelled
Bump version to 0.8.23 (#16119)
2025-10-04 12:46:01 -05:00

8.7 KiB

Creating projects

uv supports creating a project with uv init.

When creating projects, uv supports two basic templates: applications and libraries. By default, uv will create a project for an application. The --lib flag can be used to create a project for a library instead.

Target directory

uv will create a project in the working directory, or, in a target directory by providing a name, e.g., uv init foo. If there's already a project in the target directory, i.e., if there's a pyproject.toml, uv will exit with an error.

Applications

Application projects are suitable for web servers, scripts, and command-line interfaces.

Applications are the default target for uv init, but can also be specified with the --app flag.

$ uv init example-app

The project includes a pyproject.toml, a sample file (main.py), a readme, and a Python version pin file (.python-version).

$ tree example-app
example-app
├── .python-version
├── README.md
├── main.py
└── pyproject.toml

!!! note

Prior to v0.6.0, uv created a file named `hello.py` instead of `main.py`.

The pyproject.toml includes basic metadata. It does not include a build system, it is not a package and will not be installed into the environment:

[project]
name = "example-app"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = []

The sample file defines a main function with some standard boilerplate:

def main():
    print("Hello from example-app!")


if __name__ == "__main__":
    main()

Python files can be executed with uv run:

$ cd example-app
$ uv run main.py
Hello from example-project!

Packaged applications

Many use-cases require a package. For example, if you are creating a command-line interface that will be published to PyPI or if you want to define tests in a dedicated directory.

The --package flag can be used to create a packaged application:

$ uv init --package example-pkg

The source code is moved into a src directory with a module directory and an __init__.py file:

$ tree example-pkg
example-pkg
├── .python-version
├── README.md
├── pyproject.toml
└── src
    └── example_pkg
        └── __init__.py

A build system is defined, so the project will be installed into the environment:

[project]
name = "example-pkg"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = []

[project.scripts]
example-pkg = "example_pkg:main"

[build-system]
requires = ["uv_build>=0.8.23,<0.9.0"]
build-backend = "uv_build"

!!! tip

The `--build-backend` option can be used to request an alternative build system.

A command definition is included:

[project]
name = "example-pkg"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = []

[project.scripts]
example-pkg = "example_pkg:main"

[build-system]
requires = ["uv_build>=0.8.23,<0.9.0"]
build-backend = "uv_build"

The command can be executed with uv run:

$ cd example-pkg
$ uv run example-pkg
Hello from example-pkg!

Libraries

A library provides functions and objects for other projects to consume. Libraries are intended to be built and distributed, e.g., by uploading them to PyPI.

Libraries can be created by using the --lib flag:

$ uv init --lib example-lib

!!! note

Using `--lib` implies `--package`. Libraries always require a packaged project.

As with a packaged application, a src layout is used. A py.typed marker is included to indicate to consumers that types can be read from the library:

$ tree example-lib
example-lib
├── .python-version
├── README.md
├── pyproject.toml
└── src
    └── example_lib
        ├── py.typed
        └── __init__.py

!!! note

A `src` layout is particularly valuable when developing libraries. It ensures that the library is
isolated from any `python` invocations in the project root and that distributed library code is
well separated from the rest of the project source.

A build system is defined, so the project will be installed into the environment:

[project]
name = "example-lib"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = []

[build-system]
requires = ["uv_build>=0.8.23,<0.9.0"]
build-backend = "uv_build"

!!! tip

You can select a different build backend template by using `--build-backend` with `hatchling`,
`uv_build`, `flit-core`, `pdm-backend`, `setuptools`, `maturin`, or `scikit-build-core`. An
alternative backend is required if you want to create a [library with extension modules](#projects-with-extension-modules).

The created module defines a simple API function:

def hello() -> str:
    return "Hello from example-lib!"

And you can import and execute it using uv run:

$ cd example-lib
$ uv run python -c "import example_lib; print(example_lib.hello())"
Hello from example-lib!

Projects with extension modules

Most Python projects are "pure Python", meaning they do not define modules in other languages like C, C++, FORTRAN, or Rust. However, projects with extension modules are often used for performance sensitive code.

Creating a project with an extension module requires choosing an alternative build system. uv supports creating projects with the following build systems that support building extension modules:

Specify the build system with the --build-backend flag:

$ uv init --build-backend maturin example-ext

!!! note

Using `--build-backend` implies `--package`.

The project contains a Cargo.toml and a lib.rs file in addition to the typical Python project files:

$ tree example-ext
example-ext
├── .python-version
├── Cargo.toml
├── README.md
├── pyproject.toml
└── src
    ├── lib.rs
    └── example_ext
        ├── __init__.py
        └── _core.pyi

!!! note

If using `scikit-build-core`, you'll see CMake configuration and a `main.cpp` file instead.

The Rust library defines a simple function:

use pyo3::prelude::*;

#[pyfunction]
fn hello_from_bin() -> String {
    "Hello from example-ext!".to_string()
}

#[pymodule]
fn _core(m: &Bound<'_, PyModule>) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(hello_from_bin, m)?)?;
    Ok(())
}

And the Python module imports it:

from example_ext._core import hello_from_bin


def main() -> None:
    print(hello_from_bin())

The command can be executed with uv run:

$ cd example-ext
$ uv run example-ext
Hello from example-ext!

!!! important

When creating a project with maturin or scikit-build-core, uv configures [`tool.uv.cache-keys`](https://docs.astral.sh/uv/reference/settings/#cache-keys)
to include common source file types. To force a rebuild, e.g. when changing files outside
`cache-keys` or when not using `cache-keys`, use `--reinstall`.

Creating a minimal project

If you only want to create a pyproject.toml, use the --bare option:

$ uv init example --bare

uv will skip creating a Python version pin file, a README, and any source directories or files. Additionally, uv will not initialize a version control system (i.e., git).

$ tree example-bare
example-bare
└── pyproject.toml

uv will also not add extra metadata to the pyproject.toml, such as the description or authors.

[project]
name = "example"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []

The --bare option can be used with other options like --lib or --build-backend — in these cases uv will still configure a build system but will not create the expected file structure.

When --bare is used, additional features can still be used opt-in:

$ uv init example --bare --description "Hello world" --author-from git --vcs git --python-pin