Skip to main content

Scaffold opinionated uv Python projects

Project description

nuv

PyPI version Python versions License PyPI monthly downloads Downloads Wheel CI Publish to PyPI Coverage Lint: Ruff Types: ty

Scaffold opinionated uv Python projects — tests passing, quality tooling green, out of the box.

Links: PyPI | Repository | Issues

nuv new my-tool

That's it. You get a working project with argparse, logging, 100% test coverage, ruff, and ty all green from commit zero.

Install

uv tool install nuv

Run without installing

uvx nuv new my-tool

Usage

nuv new <name>                              # creates ./<name>/, syncs deps, prints tool install command
nuv new <name> --at <path>                  # creates at an explicit path
nuv new <name> --archetype spark            # PySpark 4 project with notebooks
nuv new <name> --python-version 3.13        # override default Python version
nuv new <name> --install none               # scaffold + sync, skip tool install
nuv new <name> --install command-only       # log install command, do not execute
nuv new <name> --keep-on-failure            # keep generated files if sync/install fails

Archetypes

script (default)

A single-file CLI tool with argparse and logging.

nuv new my-tool
my-tool/
├── main.py          # argparse + logging + PROJECT_NAME constant
├── _logging.py
├── pyproject.toml   # pytest (100% cov), ruff, ty, uv dev deps
├── README.md
└── tests/
    ├── __init__.py
    └── test_main.py  # passing test from day one

spark

A PySpark 4 project with src-layout package, chispa testing, and dual notebooks (Jupyter + marimo).

nuv new my-spark-app --archetype spark
my-spark-app/
├── main.py                          # entry point: parse args, create session, run job
├── pyproject.toml                   # pyspark 4, chispa, pytest, ruff, ty, notebooks
├── README.md
├── src/my_spark_app/
│   ├── __init__.py
│   ├── _logging.py                  # suppresses noisy Spark/Py4J loggers
│   ├── config.py                    # CLI args > env vars > defaults
│   ├── session.py                   # SparkSession factory
│   └── jobs/
│       ├── __init__.py
│       └── example.py               # example transform (filter, tested with chispa)
├── tests/
│   ├── __init__.py
│   ├── conftest.py                  # session-scoped SparkSession fixture
│   └── test_example.py              # 8 tests, 100% coverage
└── notebooks/
    ├── explore.ipynb                # Jupyter notebook
    └── explore_marimo.py            # marimo reactive notebook

Default Python version: 3.13 (configurable with --python-version).

After nuv new --archetype spark, all of these pass immediately:

uv run pytest          # 8 tests, 100% coverage
uv run ruff check .    # clean
uv run ty check        # clean

Notebooks are an optional dependency group:

uv sync --group notebooks
uv run jupyter lab notebooks/
uv run marimo run notebooks/explore_marimo.py

Quality out of the box

Every generated project ships with these tools configured and green:

Tool Config
pytest 100% branch coverage enforced
ruff lint + format
ty type checking

By default, nuv new logs the command you can run to install the generated project as a tool:

uv tool install --editable <project-path>

Why

uv init produces a stub. The gap between that and "actually writing code" is annoying when you create projects frequently. nuv closes it.

Future archetypes

nuv new my-api --archetype fastapi   # coming soon

Two-layer installation roadmap

We are evolving nuv toward two explicit layers:

  1. Install nuv anywhere via uv tool install (or run without install using uvx).
  2. Install generated projects explicitly when you want a tool install (nuv new now defaults to command-only guidance).

See the design brainstorm and phased proposal in docs/plans/2026-02-26-two-layer-installation.md.

Publishing to PyPI

This project is configured for trusted publishing from GitHub Actions.

  1. Create a PyPI project named nuv and add the GitHub OIDC publisher for this repository.
  2. Push a version tag (for example, v0.1.0).
  3. The publish-pypi workflow will build and upload the distribution to PyPI.

Release checklist

  1. Bump [project].version in pyproject.toml using semver (X.Y.Z).
  2. Create and push a matching tag: vX.Y.Z.
  3. Confirm GitHub Actions publish-pypi succeeds.
  4. Verify install paths:
    • uv tool install nuv && nuv --help
    • uvx nuv --help
    • uvx nuv new smoke --at /tmp/nuv-smoke && cd /tmp/nuv-smoke && uv run pytest

After release, install with:

uv tool install nuv

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nuv-0.2.1.tar.gz (59.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nuv-0.2.1-py3-none-any.whl (18.1 kB view details)

Uploaded Python 3

File details

Details for the file nuv-0.2.1.tar.gz.

File metadata

  • Download URL: nuv-0.2.1.tar.gz
  • Upload date:
  • Size: 59.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nuv-0.2.1.tar.gz
Algorithm Hash digest
SHA256 43b80b3d3301899ec74a1f8848d2eceacc7752321ab3a7ab10c85122144bab04
MD5 316750280d7293e230147c5e67965484
BLAKE2b-256 5c2698b63575ccfc1a7bec7974aea74e14b9a0c7eebab1b9e11e1b2ddcb6ef33

See more details on using hashes here.

Provenance

The following attestation bundles were made for nuv-0.2.1.tar.gz:

Publisher: publish-pypi.yml on stevencarpenter/nuv

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nuv-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: nuv-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 18.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nuv-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1ce71fd691acbecebfaec6fef2191cff701b217cae8a3f148c83bc732e98a34d
MD5 206e31bf31ce3343940aac39fdbf33db
BLAKE2b-256 8aed5f1655a83bc1a5bb24ec3760e3f6bbba3e059afa3c67aa7a43c5b18eab8d

See more details on using hashes here.

Provenance

The following attestation bundles were made for nuv-0.2.1-py3-none-any.whl:

Publisher: publish-pypi.yml on stevencarpenter/nuv

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page