# uv init: project types, flags, and examples


The [uv](https://pydevtools.com/handbook/reference/uv.md) command `uv init` creates a new Python project with a `pyproject.toml`, a [virtual environment](https://pydevtools.com/handbook/explanation/what-is-a-virtual-environment.md), and a [lockfile](https://pydevtools.com/handbook/reference/uv.md). Different flags produce different project layouts — applications, reusable libraries, packageable CLI tools, or a minimal scaffold — each suited to a specific use case.

| Flag | Build System | Structure | Entry Point | Distribution | Use Case |
|------|--------------|-----------|-------------|--------------|----------|
| `--app` (default) | No | Flat | `main.py` | Not intended | Web apps, scripts |
| `--lib` | Yes | `src/` layout | None | PyPI packages | Reusable libraries |
| `--package` | Yes | `src/` layout | Console script | Installable apps | CLI tools |
| `--bare` | No | Minimal | None | Manual setup | Custom projects |
| `--no-package` | No | Flat | `main.py` | Explicitly blocked | Internal apps |

## Common uv init commands

### `uv init my-project`

The default form creates a new directory and an application project inside it:

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

The generated layout contains a `pyproject.toml`, `.python-version`, `README.md`, `.gitignore`, and a sample `main.py`:

```python {filename="main.py"}
def main():
    print("Hello from my-project!")


if __name__ == "__main__":
    main()
```

Run the script with `uv run main.py`. On first run, uv creates the `.venv/` directory and writes a `uv.lock` file pinning transitive dependencies.

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/reference/python-packaging-user-guide.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` alongside `--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 --package`

Use `--package` for applications that should be installable as distributable packages, such as [command-line tools](https://pydevtools.com/handbook/reference/uvx.md):

```bash
uv init --package my-cli
```

This combines the `src/` layout from `--lib` with a `[project.scripts]` table:

```toml {filename="pyproject.toml"}
[project.scripts]
my-cli = "my_cli:main"
```

When the project is installed (for example with `uv tool install .` or `pip install .`), a `my-cli` executable appears on the user's `PATH` and calls `my_cli.main()`. Use `--package` instead of `--app` when the CLI is meant to be installed rather than run out of the source directory.

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

Build system. Libraries and packageable applications include a `[build-system]` table for creating wheels and source distributions. Applications and bare projects omit this because they are not meant to be packaged.

Project structure. Libraries and packageable applications use the `src/` layout, which improves testing isolation by preventing accidental imports from the working directory. Plain applications use a flat structure for simplicity.

Entry points. Packageable applications define `[project.scripts]` entries that become executable commands when the package is installed. Plain applications rely on `uv run main.py` instead.

## Learn more

- [uv reference](https://pydevtools.com/handbook/reference/uv.md)
- [How to create your first Python project](https://pydevtools.com/handbook/tutorial/create-your-first-python-project.md)
- [src layout vs flat layout: which to use and why](https://pydevtools.com/handbook/explanation/src-layout-vs-flat-layout.md)
- [What is a build backend?](https://pydevtools.com/handbook/explanation/what-is-a-build-backend.md)
- [Why does uv use hatch as a backend?](https://pydevtools.com/handbook/explanation/why-does-uv-use-hatch-as-a-backend.md)
- [Official `uv init` reference](https://docs.astral.sh/uv/reference/cli/#uv-init)
- [Official uv project concepts](https://docs.astral.sh/uv/concepts/projects/init/)
