Scaffold opinionated uv Python projects
Project description
nuv
Scaffold opinionated uv Python projects — tests passing, quality tooling green, out of the box.
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
Pre-release fallback (before first PyPI release)
uv tool install git+https://github.com/stevencarpenter/nuv
uvx --from git+https://github.com/stevencarpenter/nuv 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> --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
What you get
my-tool/
├── main.py # argparse + logging + PROJECT_NAME constant
├── pyproject.toml # pytest (100% cov), ruff, ty, uv dev deps
├── README.md
└── tests/
├── __init__.py
└── test_main.py # passing test from day one
By default, nuv new logs the command you can run to install the generated project as a tool:
uv tool install --editable <project-path>
After nuv new, all of these pass immediately:
uv run pytest # 1 test, 100% coverage
uv run ruff check . # clean
uv run ty check # clean
Project quality
| Tool | Config |
|---|---|
| pytest | 100% branch coverage enforced |
| ruff | lint + format |
| ty | type checking |
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
The --archetype flag is reserved for upcoming project types:
nuv new my-api --archetype fastapi # coming soon
nuv new my-job --archetype spark # coming soon
Two-layer installation roadmap
We are evolving nuv toward two explicit layers:
- Install
nuvanywhere viauv tool install(or run without install usinguvx). - Install generated projects explicitly when you want a tool install (
nuv newnow 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.
- Create a PyPI project named
nuvand add the GitHub OIDC publisher for this repository. - Push a version tag (for example,
v0.1.0). - The
publish-pypiworkflow will build and upload the distribution to PyPI.
Release checklist
- Bump
[project].versioninpyproject.tomlusing semver (X.Y.Z). - Create and push a matching tag:
vX.Y.Z. - Confirm GitHub Actions
publish-pypisucceeds. - Verify install paths:
uv tool install nuv && nuv --helpuvx nuv --helpuvx 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nuv-0.1.0.tar.gz.
File metadata
- Download URL: nuv-0.1.0.tar.gz
- Upload date:
- Size: 45.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aa94be2ca43b3077cf0086e7e13f5adea9d5d929299f0572803dd49f655d9794
|
|
| MD5 |
853bcff84279f053cff7dbcf1a149031
|
|
| BLAKE2b-256 |
23c68ef39ef7390c1e6f7f7e32dd39ff612c775805d1b4a4714769d3dac522eb
|
Provenance
The following attestation bundles were made for nuv-0.1.0.tar.gz:
Publisher:
publish-pypi.yml on stevencarpenter/nuv
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nuv-0.1.0.tar.gz -
Subject digest:
aa94be2ca43b3077cf0086e7e13f5adea9d5d929299f0572803dd49f655d9794 - Sigstore transparency entry: 1002668916
- Sigstore integration time:
-
Permalink:
stevencarpenter/nuv@7cc47746a3ad014380e0a018bcf23d244c6107ac -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/stevencarpenter
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@7cc47746a3ad014380e0a018bcf23d244c6107ac -
Trigger Event:
push
-
Statement type:
File details
Details for the file nuv-0.1.0-py3-none-any.whl.
File metadata
- Download URL: nuv-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
55f6cb953fda26691681a17c03b31f0b782822a8caab9bbd5c7a1dddde4ae47b
|
|
| MD5 |
114395ad341cac1a746fa4eda52a6018
|
|
| BLAKE2b-256 |
2f17e53e8aadc8a6ec0c72cb5575ebc3909c19363e4b6920d70b7cda6935bf7a
|
Provenance
The following attestation bundles were made for nuv-0.1.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on stevencarpenter/nuv
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nuv-0.1.0-py3-none-any.whl -
Subject digest:
55f6cb953fda26691681a17c03b31f0b782822a8caab9bbd5c7a1dddde4ae47b - Sigstore transparency entry: 1002668923
- Sigstore integration time:
-
Permalink:
stevencarpenter/nuv@7cc47746a3ad014380e0a018bcf23d244c6107ac -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/stevencarpenter
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@7cc47746a3ad014380e0a018bcf23d244c6107ac -
Trigger Event:
push
-
Statement type: