UV


uv is a new and an extremely fast Python package and project manager, written in Rust. uv uses a global caching system which makes it more efficient in terms of storage and package installation time. Unlike pip and other package managers, if there are multiple projects that needs a package (for example - flask) at a time, uv will install it once and use the same package for all the current projects without any issue which saves storage space by avoiding duplicate installation and also saves time.

Installation


There are different ways to install UV. You can find different ways of installing UV from here. However, in this tutorial, we’ll use Homebrew to install UV as it is easier to install packages using Homebrew in MacOS and Linux. You can install Homebrew from here. You can install uv using Homebrew using the following command:

brew install uv

Once it is installed successfully, you can run the following command to check if that works fine.

uv --version

It should print the version of uv.

Setup Project Using UV


Let’s say you want to create a project named new_project in your Desktop. For that, change your current directory to Desktop and write the following command:

uv init new_project

If the command works fine, it’ll show a message with the location where it initialized that project. This command will create a new directory in the Desktop called new_project. However, if you want to use an existing directory to setup your application, you can run the command below:

uv init

We aren’t using any options in the above commands. However, uv has some options to choose from to create project. --app is the default option when we run uv init <project_name>. That means, it instead runs the command uv init <project_name> --app by default. Most of the time we want to use the default option as it creates a simple project structure. We can also use another option --lib if we want to work on a project that will be built and distributed as a python package.

The default option will create some files initially in the desired directory. It’ll initialize the directory as a git repository. So, there will be a .git directory in there. The other files are:

  • .gitignore: contains the files and directories to ignore in the commit.
  • .python-version: file containing information about the version of python the app is using.
  • main.py: the main python file of the project.
  • pyproject.toml: contains information about the project e.g., name, version, description, dependencies etc.
  • README.md: to add documentation for the project.

Install and Remove Python Package


Instead of using pip, we’ll install required package using the following command in uv:

uv add <package_name>

For example, if you want to install flask and requests library using uv, you can run the following command:

uv add flask requests

It’ll automatically create a virtual environment for the project and show the path of the environment. It’ll create a directory called .venv in the root directory and update the pyproject.toml file to list the dependencies. Moreover, it’ll create a new file called uv.lock which records the exact version of all the dependencies of the project. It ensures that our environment is perfectly reproducible. You can run the following command from your project directory to visualize and understand the dependencies of your project:

uv tree

Now, to remove a python package from your environment, use the following command:

uv remove <package_name>

uv will automatically update the uv.lock and pyproject.toml file when you add and remove a package.

Run Python Script in UV Environment


Now we have a python environment setup for our project. In old system, to run a python script, we used to use the command python <script.py>. However, as you’ve noticed that we don’t activate any environment in uv. Therefore, in order to run a script in uv we use the command:

uv run <script_name.py>

For example - to run main.py file in your project, you’ll write uv run main.py. Now, to make sure that uv is using the python environment created for that particular project, you can write the following code in your main.py file and then run the uv run main.py command:

import sys


def main():
    print(sys.executable)


if __name__ == "__main__":
    main()

If you run your main.py file now, you’ll see that the python executable path is <path>/<your_app_name>/.venv/bin/python3 which means that uv is using the correct python.

NOTE: The good thing about uv is that even if you delete the .venv/ directory from the project directory and then you run the uv run main.py command, uv will automatically create the environment and install the required packages using the uv.lock file and run the command.

Replicate UV Python Environment


Let’s say you want to share your code with others. Whoever wants to run your code, that person needs to create the same environment in order to run the code successfully in the new machine. However, you don’t ship your virtual environment with your code because it’ll increase the size of the repository.

uv can create the exact environment using the uv.lock and pyproject.toml file shipped along with the code. To do that, use the following command:

uv sync

Migrate from pip to uv


If you’ve an existing project created either using pip or other package managers with a requirements.txt file and you want to migrate that project to uv environment, you can migrate using the following commands:

  1. Create the uv environment project structure.
uv init
  1. Install the packages
uv add -r requirements.txt

Now, if you want to rely solely on uv in future, you can delete the requirements.txt file.

Replace pipx with uv


pipx is used to install tools such as formatter, linter etc in to format and write python code following best practices since we don’t want to install those tools for a particular project separately. So, pipx installs those tools globally which we can now do using uv.

For example - if you want to install ruff using uv, you run the following command:

uv tool install ruff

This command installs ruff and will add to the PATH. You can check the path using which ruff command.

If you want to uninstall a tool such as ruff installed using uv, you can run the command below:

uv tool uninstall ruff

You can list the tools installed in your machine using uv using the command:

uv tool list

You can also upgrade all of your tools at once using the following command:

uv tool upgrade --all

uv can also use tools like ruff without installing it permanently on your device. If you want to use tools for some of your project only a few times, uv will make your life easier. You can run the following command to run ruff check command without installing ruff:

uv tool run ruff check

Alternatively, you can use the short command:

uvx ruff check

That’s all for this blog. Although uv has a lot of functionalities which weren’t covered in this blog, I’ll try to add them as I become more familiar with the other functionalities.