binary file
Add blog post: Managing a Python project with uv in 2026
Add blog post: Managing a Python project with uv in 2026 New post covering uv for project/dependency management and ruff for linting/formatting. Add toml CodeMirror mode for syntax highlighting in toml code blocks.
@@ -0,0 +1,131 @@---title: Managing a Python project with uv in 2026slug: managing-a-python-project-with-uv-in-2026date: 2026-04-05publish_date: 2026-04-05tags: codingdescription: How I set up and manage Python projects in 2026 using uv and ruff. Two tools and one config file replace everything.cover_image: uv-terminal.webp---Setting up a Python project used to mean juggling multiple tools for package management, Python versions, and virtual environments. I used to use pipenv, pyenv, and Black but I've since moved on. In 2026 I use `uv` for project management and `ruff` for linting and formatting. Two tools, one config file.## Installing uv[uv](https://docs.astral.sh/uv/) is a single binary that replaces pip, pipenv, pyenv, and virtualenv. It's written in Rust by Astral and it's extremely fast.```shellcurl -LsSf https://astral.sh/uv/install.sh | sh```## Starting a new projectInstead of manually creating a `Pipfile` or `requirements.txt`, run `uv init` and you get a project scaffold with a `pyproject.toml` ready to go.```shelluv init my-projectcd my-project```This gives you:```my-project/├── .python-version├── README.md├── main.py└── pyproject.toml```No `Pipfile`, no `setup.cfg`, no `requirements.txt`. Just `pyproject.toml`.## Managing Python versionsYou don't need pyenv anymore. uv handles downloading and managing Python versions for you.```shelluv python pin 3.13uv python install```This writes `3.13` to `.python-version` and installs it if you don't already have it. That's it.## Adding dependenciesAdding dependencies updates your `pyproject.toml` and `uv.lock` in one step.```shelluv add flask requestsuv add --dev pytest ruff```When you clone the project on another machine or set up CI, `uv sync` installs everything from the lockfile.## Running things`uv run` executes inside the project's virtual environment without you needing to activate anything. No more `pipenv shell` or `source .venv/bin/activate`.```shelluv run python main.pyuv run pytest```## Linting and formatting with RuffI used to use Black, Flake8, and isort separately but [Ruff](https://docs.astral.sh/ruff/) handles all of that now. It's from the same team that makes uv and it's just as fast. The formatter is designed as a drop-in replacement for Black with near-identical output, so switching won't mean a massive reformatting commit across your codebase.```shelluv run ruff check .uv run ruff format .````ruff check` handles linting and import sorting. `ruff format` handles code formatting. You configure both in `pyproject.toml`:```toml[tool.ruff]line-length = 88target-version = "py313"[tool.ruff.lint]select = ["E", "F", "I", "UP"][tool.ruff.format]quote-style = "double"````E` and `F` are the pycodestyle and pyflakes rules that Flake8 used by default. `I` is isort-compatible import sorting. `UP` is pyupgrade which modernizes your syntax automatically. You can browse the full [rule list](https://docs.astral.sh/ruff/rules/) and add what makes sense for your project.## The full pyproject.tomlHere's what a complete `pyproject.toml` looks like. This replaces the `Pipfile`, `Pipfile.lock`, `.flake8`, and `.isort.cfg` I used to have scattered across my projects.```toml[project]name = "my-project"version = "0.1.0"description = ""readme = "README.md"requires-python = ">=3.13"dependencies = [ "flask", "requests",][dependency-groups]dev = [ "pytest", "ruff",][tool.ruff]line-length = 88target-version = "py313"[tool.ruff.lint]select = ["E", "F", "I", "UP"][tool.ruff.format]quote-style = "double"```That's all you need to get a Python project off the ground in 2026. If you're still juggling multiple tools and config files give uv and ruff a try, I don't think you'll go back.
@@ -5,6 +5,7 @@ import "codemirror/mode/javascript/javascript.js";import "codemirror/mode/htmlmixed/htmlmixed.js";import "codemirror/mode/css/css.js";import "codemirror/mode/shell/shell.js";import "codemirror/mode/toml/toml.js";import "codemirror/lib/codemirror.css";import "codemirror/theme/material-darker.css";