# uv init: project types, flags, and examples


The [uv](https://pydevtools.com/handbook/reference/uv.md) command `uv init` creates a new Python project. It generates a `pyproject.toml` and the project scaffold; the [virtual environment](https://pydevtools.com/handbook/explanation/what-is-a-virtual-environment.md) and [lockfile](https://pydevtools.com/handbook/explanation/what-is-a-lock-file.md) 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 init` became packaged-by-default: it produces a `src/` layout with `uv_build` and a console-script entry point. The earlier flat `main.py` layout is available with `--no-package`.
> [What is the uv build backend (uv_build)?](https://pydevtools.com/handbook/explanation/what-is-the-uv-build-backend.md) explains the backend those projects declare.

| 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:

```bash
uv init my-project
```

The 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__.py
```

The `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`:

```toml {filename="pyproject.toml"}
[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`:

```bash
uv init --no-package my-project
```

Running `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](https://pydevtools.com/handbook/explanation/what-is-pypi.md) or imported by other projects:

```bash
uv init --lib my-lib
```

The 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.typed
```

uv 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`](https://docs.astral.sh/uv/concepts/build-backend/) as the default [build backend](https://pydevtools.com/handbook/explanation/what-is-a-build-backend.md). To use a different backend ([hatchling](https://pydevtools.com/handbook/reference/hatch.md#hatchling-build-backend), [flit-core](https://pydevtools.com/handbook/reference/flit.md#flit-core-build-backend), [pdm-backend](https://pydevtools.com/handbook/reference/pdm.md#pdm-backend), [setuptools](https://pydevtools.com/handbook/reference/setuptools.md#using-setuptools-as-a-build-backend-with-uv), [maturin](https://www.maturin.rs/), or [scikit-build-core](https://scikit-build-core.readthedocs.io/)), pass `--build-backend`, which works with the default project type as well as `--lib`. The empty `py.typed` marker tells [type checkers](https://pydevtools.com/handbook/explanation/how-do-mypy-pyright-and-ty-compare.md) the package ships inline type information.

### `uv init --no-package`

Use `--no-package` for scripts and internal applications that you never plan to distribute:

```bash
uv init --no-package my-script
```

This produces a flat layout with a `main.py` and no `[build-system]` table, the layout that `uv init` generated before it became packaged-by-default. 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](https://pydevtools.com/handbook/reference/python-packaging-user-guide.md).

### `uv init --bare`

Use `--bare` when you only want a minimal `pyproject.toml`:

```bash
uv init --bare
```

No 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:

```bash
uv init --python 3.12 my-project
```

uv 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](https://pydevtools.com/handbook/reference/python-packaging-user-guide.md). `--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`.

### Pick your next step

- **Building an application?** [Create your first Python project](https://pydevtools.com/handbook/tutorial/create-your-first-python-project.md) uses the default packaged app layout.
- **Building a library?** [Build and publish a Python package](https://pydevtools.com/handbook/tutorial/build-and-publish-a-python-package.md) takes a `--lib` project through to PyPI.
- **Writing a quick script?** [Write a self-contained script](https://pydevtools.com/handbook/how-to/how-to-write-a-self-contained-script.md) skips project setup entirely with PEP 723 metadata.
- **Managing multiple packages?** [Set up a Python monorepo with uv workspaces](https://pydevtools.com/handbook/how-to/how-to-set-up-a-python-monorepo-with-uv-workspaces.md) coordinates several projects.
- **Choosing src vs flat layout?** [src layout vs flat layout](https://pydevtools.com/handbook/explanation/src-layout-vs-flat-layout.md) explains the trade-offs.
