uv init: project types, flags, and examples
The uv command uv init creates a new Python project. It generates a pyproject.toml and the project scaffold; the virtual environment and lockfile are created lazily on the first uv run, uv sync, or uv add. Different flags produce different project layouts: packaged applications, reusable libraries, unpackaged scripts, or a minimal scaffold, each suited to a specific use case.
Note
uv 0.12.0 (July 2026) changed the default: uv init now produces a packaged src/ layout with uv_build and a console-script entry point. The previous flat main.py layout is available with --no-package.
| Flag | Build System | Structure | Entry Point | Use Case |
|---|---|---|---|---|
(default) / --app |
uv_build |
src/ |
Console script | Apps, CLI tools |
--package |
uv_build |
src/ |
Console script | Same as the default since 0.12.0 |
--lib |
uv_build |
src/ |
None | Reusable libraries |
--no-package |
None | Flat | main.py |
Scripts, internal apps |
--bare |
None | Minimal | None | Custom projects |
Common uv init commands
uv init my-project
The default form creates a new directory and a packaged application project inside it:
uv init my-projectThe generated layout places source code under src/, includes a [build-system] table, and defines a console-script entry point:
my-project/
├── .gitignore
├── .python-version
├── pyproject.toml
├── README.md
└── src/
└── my_project/
└── __init__.pyThe pyproject.toml wires up uv_build and maps the my-project command to the main function in my_project. uv fills authors from your git config (omitting it when git has no user configured) and sets requires-python from the interpreter uv itself discovers, which is not always the python3 on your PATH, or from the version passed via --python:
[project]
name = "my-project"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
authors = [
{ name = "Ada Lovelace", email = "ada@example.com" }
]
requires-python = ">=3.13"
dependencies = []
[project.scripts]
my-project = "my_project:main"
[build-system]
requires = ["uv_build>=0.12.0,<0.13.0"]
build-backend = "uv_build"Run the project with uv run my-project. On first run, uv creates the .venv/ directory, installs the project in editable mode, and writes a uv.lock file pinning transitive dependencies.
To get the previous flat main.py layout without a build system, pass --no-package:
uv init --no-package my-projectRunning uv init with no arguments initializes a project in the current directory instead of creating a new one. This is the right choice when the directory already exists (for example, a freshly cloned git repository).
uv init --lib
Use --lib for libraries meant to be published to PyPI or imported by other projects:
uv init --lib my-libThe result uses the src/my_lib/ layout, which is the recommended structure for libraries because it forces imports to resolve against the installed package rather than the working directory:
my-lib/
├── .gitignore
├── .python-version
├── pyproject.toml
├── README.md
└── src/
└── my_lib/
├── __init__.py
└── py.typeduv also runs git init in the new project directory by default. Pass --vcs none to skip it.
The pyproject.toml includes a full [build-system] table using uv_build as the default build backend. To use a different backend (hatchling, flit-core, pdm-backend, setuptools, maturin, or scikit-build-core), pass --build-backend, which works with the default project type as well as --lib. The empty py.typed marker tells type checkers the package ships inline type information.
uv init --no-package
Use --no-package for scripts and internal applications that you never plan to distribute:
uv init --no-package my-scriptThis produces a flat layout with a main.py and no [build-system] table, the layout that uv init generated before version 0.12.0. Run the script with uv run main.py. Without a build system, uv does not treat it as a package and will not install it into the project environment; it is not intended for distribution to PyPI.
uv init --bare
Use --bare when you only want a minimal pyproject.toml:
uv init --bareNo sample code, no README.md, no .python-version, no src/ directory, just a pyproject.toml with essential metadata. This is the right choice when adding uv to an existing project with its own structure, or when scripting project creation and you want to generate files yourself.
uv init with a specific Python version
Pass --python to pin the new project to a specific Python version:
uv init --python 3.12 my-projectuv writes 3.12 to .python-version and sets requires-python = ">=3.12" in pyproject.toml. If Python 3.12 is not already installed, uv downloads a managed build automatically on the next uv run or uv sync. The same flag works with any project type: uv init --lib --python 3.13 my-lib creates a library pinned to Python 3.13.
To change the Python version of an existing uv project instead, edit .python-version and requires-python, or use uv python pin 3.12.
How project types differ
The project types differ in three areas:
Project structure. --app and --lib use a src/ layout that keeps source code separate from the project root. --no-package produces a flat layout with main.py at the root. --bare generates only a minimal pyproject.toml with no sample code or directories.
Build system. The --app and --lib projects include a [build-system] table using uv_build, which lets the project be installed as a package, imported from tests, and published to PyPI. --no-package and --bare omit this, since they are not intended for distribution.
Entry points. The default --app project adds a [project.scripts] entry that becomes a runnable command (uv run my-project). --lib omits the scripts entry because a library is imported, not executed. --no-package provides a main.py instead, run with uv run main.py.
Learn more
- uv reference
- How to create your first Python project
- src layout vs flat layout: which to use and why
- What is a build backend?
- Why does uv use hatch as a backend? (why packaged projects used Hatchling before
uv_buildbecame the default in July 2025) - Official
uv initreference - Official uv project concepts