Skip to content

mgwilt/nx-uv

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

92 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@mgwilt/nx-uv

Nx plugin for running uv workflows in Nx monorepos.

CI Coverage lines Coverage functions Coverage statements Coverage branches Coverage floor npm release

Why this plugin exists

Nx provides a consistent task graph, caching, and affected-based CI so large repos run faster and more predictably. A common operational gap is that Python workflows powered by uv often stay in separate shell scripts and one-off CI jobs, so they miss the same build/test orchestration used by the rest of the monorepo.

@mgwilt/nx-uv bridges that gap by turning common uv workflows into Nx-native targets and adding inference/generators so teams can standardize command execution, reduce bespoke pipeline logic, and manage Python alongside other stacks in a single CI model instead of maintaining a parallel toolchain path.

When to use this plugin

  • Run uv commands through Nx targets instead of ad-hoc shell scripts.
  • Infer useful uv targets from existing pyproject.toml files.
  • Scaffold uv-ready Python projects and workspace config.
  • Keep Python work in the same task graph, caching, and CI flow as the rest of your monorepo.

Tools

  • Executors for uv command families:
    • @mgwilt/nx-uv:project
    • @mgwilt/nx-uv:uv
    • @mgwilt/nx-uv:pip
    • @mgwilt/nx-uv:tool
    • @mgwilt/nx-uv:python
    • @mgwilt/nx-uv:auth
    • @mgwilt/nx-uv:cache
    • @mgwilt/nx-uv:self
    • @mgwilt/nx-uv:studio
  • Generators:
    • @mgwilt/nx-uv:workspace
    • @mgwilt/nx-uv:project
    • @mgwilt/nx-uv:integration
    • @mgwilt/nx-uv:convert
  • Nx plugin inference (createNodesV2) for pyproject.toml.

Install

Prerequisites:

  • Nx workspace
  • uv installed and available on PATH

Install the plugin:

pnpm add -D @mgwilt/nx-uv

Interactive studio (TUI)

Launch the interactive monorepo manager directly with pnpm dlx (recommended):

pnpm dlx -p @mgwilt/nx-uv nx-uv tui

Shorthand (when supported by your pnpm version/environment):

pnpm dlx @mgwilt/nx-uv tui

The studio provides:

  • Workspace setup and inference configuration
  • Python app/lib/script generation
  • Integration template scaffolding
  • Convert existing projects to nx-uv defaults
  • Nx target execution across all projects
  • Ad-hoc uv command execution
  • Preview-before-apply flow for mutating actions

Optional flags:

  • --cwd=<path> scan and manage a workspace from a specific directory
  • --readonly disable mutation/apply operations
  • --initial-view=<dashboard|workspace|project|integration|convert|inference|tasks|uv>

If plugin inference is configured with includeGlobalTargets: true and a root uv workspace exists, the root inferred project also gets a <targetPrefix>tui target (for example uv:tui).

Brand new monorepo example

This walkthrough creates a new Nx monorepo and uses this plugin to scaffold a working uv + Python example.

  1. Create a new workspace:
pnpm create nx-workspace@latest acme-monorepo --preset=ts --packageManager=pnpm --nxCloud=skip --interactive=false
cd acme-monorepo
  1. Install this plugin and initialize workspace-level uv config:
pnpm add -D @mgwilt/nx-uv
pnpm nx g @mgwilt/nx-uv:workspace --name=acme --membersGlob='packages/py/*'
  1. Generate a Python app and scaffold integrations:
pnpm nx g @mgwilt/nx-uv:project api --projectType=app --directory=packages/py
pnpm nx g @mgwilt/nx-uv:integration --template=fastapi --project=api
pnpm nx g @mgwilt/nx-uv:integration --template=github

Expected file tree (key files) after step 3:

acme-monorepo/
├── nx.json
├── package.json
├── pyproject.toml
├── .github/
│   └── workflows/
│       └── uv-ci.yml
└── packages/
    └── py/
        └── api/
            ├── README.md
            ├── pyproject.toml
            ├── main.py
            ├── Dockerfile.fastapi
            ├── src/
            │   └── api/
            │       ├── __init__.py
            │       └── main.py
            └── tests/
                └── test_smoke.py
  1. Add runtime and dev dependencies with uv:
cd packages/py/api
uv add fastapi uvicorn
uv add --dev pytest ruff
cd ../../..
  1. Run plugin-backed targets via Nx:
pnpm nx run api:sync
pnpm nx run api:uv
pnpm nx run api:run
pnpm nx run api:test
pnpm nx run api:build

At this point you have a working monorepo with:

  • Root pyproject.toml and uv workspace members
  • A generated api Python project under packages/py/api
  • Generated FastAPI starter files and a GitHub Actions Nx-first CI template (test, lint, typecheck, build)
  • Nx targets that run uv commands consistently in CI/local dev

Quick start (existing workspace)

  1. Add the plugin to nx.json:
{
  "plugins": [
    {
      "plugin": "@mgwilt/nx-uv",
      "options": {
        "targetPrefix": "uv:",
        "inferencePreset": "standard",
        "includeGlobalTargets": false
      }
    }
  ]
}
  1. (Optional, recommended for new repos) Initialize uv workspace config:
pnpm nx g @mgwilt/nx-uv:workspace --name=acme
  1. Generate a Python project wired for uv + Nx:
pnpm nx g @mgwilt/nx-uv:project services/api --projectType=app
  1. Run uv-backed targets:
pnpm nx run api:sync
pnpm nx run api:test
pnpm nx run api:build

Existing Python projects

If your repo already has pyproject.toml files, the plugin can infer targets (for example uv:sync, uv:run, uv:test) based on your configured targetPrefix and inference preset.

Customizing inferred targets

You can disable or override inferred targets in plugin options:

{
  "plugins": [
    {
      "plugin": "@mgwilt/nx-uv",
      "options": {
        "targetPrefix": "uv:",
        "inferencePreset": "standard",
        "inferredTargets": {
          "test": false,
          "lint": {
            "command": "run",
            "commandArgs": ["--", "ruff", "check", "src"]
          }
        }
      }
    }
  ]
}

Supported inferred target keys are: sync, run, lock, test, lint, build, tree, export, format, venv, publish.

Integration templates

Use integration templates to scaffold common uv ecosystem files for CI, containers, dependency automation, and notebook workflows.

How file output location works

  • --project=<name> sets <baseDir> to that Nx project's root.
  • --directory=<path> sets <baseDir> to that directory relative to workspace root.
  • If neither is set, <baseDir> defaults to workspace root (.).
  • Workspace-level templates always write to repo root, even if --project or --directory is provided.
  • Workspace-level templates are:
    • github
    • gitlab
    • dependency-bots
    • pre-commit

Templates by workload

CI and repo automation

Template Best for
github GitHub Actions Nx-first CI starter using nx affected
gitlab GitLab CI/CD Nx-first CI starter using nx run-many
dependency-bots Automated dependency update workflows with Renovate and Dependabot
pre-commit Local code quality hooks for uv projects using pre-commit

Services and deployment

Template Best for
fastapi Bootstrapping a FastAPI service with uv
docker Containerizing a uv project with Docker
aws-lambda Packaging uv-based AWS Lambda workloads

Data science and AI workflows

Template Best for
jupyter Registering a uv-managed Jupyter kernel
marimo Starting marimo notebook workflows
pytorch Configuring PyTorch for CPU/CUDA/ROCm, notebook workflows, and NVIDIA containerized inference
coiled Starting distributed Python experiments with Coiled

Package source configuration

Template Best for
alternative-indexes Defining custom/internal Python indexes

Command examples by workload

CI and repo automation

pnpm nx g @mgwilt/nx-uv:integration --template=github
pnpm nx g @mgwilt/nx-uv:integration --template=gitlab
pnpm nx g @mgwilt/nx-uv:integration --template=dependency-bots
pnpm nx g @mgwilt/nx-uv:integration --template=pre-commit

Services and deployment

pnpm nx g @mgwilt/nx-uv:integration --template=fastapi --project=api
pnpm nx g @mgwilt/nx-uv:integration --template=docker --project=api
pnpm nx g @mgwilt/nx-uv:integration --template=aws-lambda --project=api

Data science and AI workflows

pnpm nx g @mgwilt/nx-uv:integration --template=jupyter --project=api
pnpm nx g @mgwilt/nx-uv:integration --template=marimo --project=api
pnpm nx g @mgwilt/nx-uv:integration --template=pytorch --project=api
pnpm nx g @mgwilt/nx-uv:integration --template=pytorch --project=api --backend=rocm --includeDocker=false
pnpm nx g @mgwilt/nx-uv:integration --template=pytorch --project=api --backend=cpu --includeNotebook=false --includeDocker=false
pnpm nx g @mgwilt/nx-uv:integration --template=coiled --project=api

Package source configuration

pnpm nx g @mgwilt/nx-uv:integration --template=alternative-indexes --project=api

Common options

  • --overwrite=true replaces existing files instead of skipping them.
  • --directory=<path> writes baseDir-aware templates into a non-project directory.
  • --skipFormat=true skips formatter execution after generation.
  • --backend=<cuda|rocm|cpu> applies to template=pytorch (default: cuda).
  • --includeNotebook=<true|false> applies to template=pytorch (default: true).
  • --includeDocker=<true|false> applies to template=pytorch (default: true for cuda, false for other backends).
  • Prefer --project for app/lib scaffolds and no location flag for workspace-level templates.

Notes and pitfalls

  • Templates are starter scaffolds; you should review and harden generated files for production use.
  • Running the same template multiple times without --overwrite=true leaves existing files unchanged.
  • Workspace-level templates are intentionally global and may affect repository-wide automation.
  • template=pytorch now defaults to --backend=cuda and emits CUDA-oriented snippets by default.
  • NVIDIA inference Docker/Compose assets from template=pytorch are generated only for --backend=cuda.

Compatibility and versioning

  • Runtime uv compatibility checks verify that uv is available and executable.
  • uv 0.9.x and 0.10.x are currently the tested ranges. Other versions log a warning and continue.

Troubleshooting

Nx plugin bootstrap failures

If quality:ci fails before running tasks with worker/bootstrap errors (for example Failed to load ... Nx plugin(s)), run:

pnpm quality:bootstrap
pnpm nx reset
pnpm quality:ci

If bootstrap still fails, run direct checks to isolate whether the issue is Nx plugin startup or project logic:

pnpm quality:fallback
pnpm --version
pnpm nx --version
node -v

E2E execution permissions

The e2e suite executes a temporary shim binary from the local filesystem. In restricted environments (for example noexec mounts or sandboxed process policies), e2e tests may be skipped when executable spawning is not permitted.

In CI, an all-skipped e2e run is treated as a failure by default. Set NX_UV_ALLOW_E2E_ALL_SKIPPED=1 only in known restricted CI environments where executable shim spawning is intentionally blocked.

LLM context files

This repository publishes LLM-friendly docs artifacts:

  • llms.txt: concise index of high-signal project docs.
  • llms-full.txt: expanded inline content for the same curated sources.

Regenerate and validate them with:

pnpm llms:generate
pnpm llms:check

Additional docs

About

Nx plugin for uv workflows in Nx monorepos

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors