{"id":1648,"date":"2026-01-18T18:06:01","date_gmt":"2026-01-18T18:06:01","guid":{"rendered":"https:\/\/justinmatters.co.uk\/wp\/?p=1648"},"modified":"2026-01-18T18:06:03","modified_gmt":"2026-01-18T18:06:03","slug":"using-uv-for-python-package-management","status":"publish","type":"post","link":"https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/","title":{"rendered":"Using UV for Python Package Management"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">UV is a powerful package manager for Python. UV can supplement or even replace other tools like pip, conda, and venv. However it works a little differently so here are some notes to help with usage. Note that I have mostly been using UV on Windows but it also works on Mac and Linux.<\/p>\n\n\n\n<div class=\"wp-block-cover\"><img loading=\"lazy\" decoding=\"async\" width=\"700\" height=\"233\" class=\"wp-block-cover__image-background wp-image-1655\" alt=\"\" src=\"https:\/\/justinmatters.co.uk\/wp\/wp-content\/uploads\/2026\/01\/UV-700x233.png\" data-object-fit=\"cover\" srcset=\"https:\/\/justinmatters.co.uk\/wp\/wp-content\/uploads\/2026\/01\/UV-700x233.png 700w, https:\/\/justinmatters.co.uk\/wp\/wp-content\/uploads\/2026\/01\/UV-300x100.png 300w, https:\/\/justinmatters.co.uk\/wp\/wp-content\/uploads\/2026\/01\/UV-768x255.png 768w, https:\/\/justinmatters.co.uk\/wp\/wp-content\/uploads\/2026\/01\/UV.png 1515w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><span aria-hidden=\"true\" class=\"wp-block-cover__background has-background-dim\"><\/span><div class=\"wp-block-cover__inner-container is-layout-flow wp-block-cover-is-layout-flow\">\n<p class=\"has-text-align-center has-large-font-size wp-block-paragraph\"><\/p>\n<\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Getting Started<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">First of all you will need Python installed. You can download and install Python from <a href=\"https:\/\/www.python.org\/downloads\/\">https:\/\/www.python.org\/downloads\/<\/a> . Next you will need to get UV itself. This can be done with <code>pip install uv<\/code> and there are <a href=\"https:\/\/docs.astral.sh\/uv\/getting-started\/installation\/\">other methods as well<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">uv init<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now lets use UV to set up our project environment. To do this navigate to the folder where you want to place your project folder. Next type <code>uv init project-name<\/code> . This will create a folder called <code>project-name<\/code> inside the folder with the following structure:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u251c\u2500\u2500 \/.git\n\u251c\u2500\u2500 .gitignore  \n\u251c\u2500\u2500 .python-version \n\u251c\u2500\u2500 main.py \n\u251c\u2500\u2500 pyproject.toml \n\u2514\u2500\u2500 README.md<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">As you can see, a really nice feature of using UV to set up a project is that it also sets up all the requisites for a git repository. This means that you can then easily push your new project up to Github or another provider rather than needing to set that up as a separate step. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">uv venv<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">One thing that the uv init command does not set up is a virtual environment. To do this navigate into your new project folder and type <code>uv venv<\/code> . This will set up a .venv folder with a virtual enviroment in it which is compatible with the old venv virtual environment creator. The python version will be that specified in .python-version. You can also specify python versions and the environment name if you wish, <a href=\"https:\/\/docs.astral.sh\/uv\/pip\/environments\/\">the docs are here<\/a>. You can also use <code>uv python install<\/code> to install the latest version of Python if you get an error when trying to create the virtual environment, then use <code>uv python update-shell<\/code> to add it to your PATH. As with traditional venv virtual environments you can activate your new environment with <code>.venv\\Scripts\\activate<\/code>. You can then run <code>uv pip list<\/code>, but you will find that your virtual environment has not got any libraries in it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Adding Packages<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To add packages to your virtual environment, make sure is is activated. You could then use the command <code>uv pip install package-name<\/code> to install the required package. A good thing here is that UV tends to be a lot quicker at resolving dependencies that pip is so setting up your environment should go faster.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However this installation approach has a problem. While it installs the packages it does not add them to pyproject.toml or uv.lock. This means that when you next run uv sync, these packages will be removed from your virtual environment. This can be useful if you were unsure if a given package was going to be required but can be infuriating if you did want a package and accidentally remove it at next sync. Therefore once you are sure that you are going to want to retain a package as part of your project you should instead use <code>uv add package-name<\/code> , This will both install the package and also add it to the files UV uses for project dependencies. These dependency files are in some ways UV&#8217;s secret sauce because they allow anyone downloading your project to use them to rapidly set up their environment in the same way you have.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Running Python Files<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">So you have completed the basic UV project setup, congratulations. You can then now your python files (for example main.py which UV sets up when you use uv init) with the command <code>uv run main.py<\/code> . Be aware that this command looks in pyproject.toml and sets up your environment if it is not already set up. It is therefor e important that pyproject.toml and .python-version have compatible python versions, this will be true by default after first initialisation but if you make modifications this can lead to issues.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Other Features<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">UV has a lot of other features too like running tools and viewing dependency trees. More information on the useful things it can do can be found <a href=\"https:\/\/docs.astral.sh\/uv\/getting-started\/features\/#features\">here<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>UV is a powerful package manager for Python. UV can supplement or even replace other tools like pip, conda, and venv. However it works a&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[198,197,14,196],"class_list":["post-1648","post","type-post","status-publish","format-standard","hentry","category-data-science","tag-environment","tag-packages","tag-python","tag-uv"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Using UV for Python Package Management - Justin&#039;s Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using UV for Python Package Management - Justin&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"UV is a powerful package manager for Python. UV can supplement or even replace other tools like pip, conda, and venv. However it works a&hellip;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/\" \/>\n<meta property=\"og:site_name\" content=\"Justin&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-01-18T18:06:01+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-01-18T18:06:03+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/justinmatters.co.uk\/wp\/wp-content\/uploads\/2026\/01\/UV-700x233.png\" \/>\n<meta name=\"author\" content=\"justinmatters\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"justinmatters\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/using-uv-for-python-package-management\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/using-uv-for-python-package-management\\\/\"},\"author\":{\"name\":\"justinmatters\",\"@id\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/#\\\/schema\\\/person\\\/7c3e0740e1fef74f705c19f175f6f321\"},\"headline\":\"Using UV for Python Package Management\",\"datePublished\":\"2026-01-18T18:06:01+00:00\",\"dateModified\":\"2026-01-18T18:06:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/using-uv-for-python-package-management\\\/\"},\"wordCount\":663,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/using-uv-for-python-package-management\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/wp-content\\\/uploads\\\/2026\\\/01\\\/UV-700x233.png\",\"keywords\":[\"Environment\",\"Packages\",\"Python\",\"UV\"],\"articleSection\":[\"Data Science\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/using-uv-for-python-package-management\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/using-uv-for-python-package-management\\\/\",\"url\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/using-uv-for-python-package-management\\\/\",\"name\":\"Using UV for Python Package Management - Justin&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/using-uv-for-python-package-management\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/using-uv-for-python-package-management\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/wp-content\\\/uploads\\\/2026\\\/01\\\/UV-700x233.png\",\"datePublished\":\"2026-01-18T18:06:01+00:00\",\"dateModified\":\"2026-01-18T18:06:03+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/#\\\/schema\\\/person\\\/7c3e0740e1fef74f705c19f175f6f321\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/using-uv-for-python-package-management\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/using-uv-for-python-package-management\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/using-uv-for-python-package-management\\\/#primaryimage\",\"url\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/wp-content\\\/uploads\\\/2026\\\/01\\\/UV.png\",\"contentUrl\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/wp-content\\\/uploads\\\/2026\\\/01\\\/UV.png\",\"width\":1515,\"height\":504},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/using-uv-for-python-package-management\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using UV for Python Package Management\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/#website\",\"url\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/\",\"name\":\"Justin's Blog\",\"description\":\"Justin&#039;s Coding and Geek Blog\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/#\\\/schema\\\/person\\\/7c3e0740e1fef74f705c19f175f6f321\",\"name\":\"justinmatters\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/27cf337940887c098b79716aa7025ce782bd51de3f6b07a9dcad710bbf576c59?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/27cf337940887c098b79716aa7025ce782bd51de3f6b07a9dcad710bbf576c59?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/27cf337940887c098b79716aa7025ce782bd51de3f6b07a9dcad710bbf576c59?s=96&d=mm&r=g\",\"caption\":\"justinmatters\"},\"description\":\"Data Scientist specialising in Python, PySpark, SQL and Machine Learning\",\"sameAs\":[\"https:\\\/\\\/justinmatters.co.uk\\\/wp\\\/\",\"https:\\\/\\\/uk.linkedin.com\\\/in\\\/justin-matters-edinburgh\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using UV for Python Package Management - Justin&#039;s Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/","og_locale":"en_US","og_type":"article","og_title":"Using UV for Python Package Management - Justin&#039;s Blog","og_description":"UV is a powerful package manager for Python. UV can supplement or even replace other tools like pip, conda, and venv. However it works a&hellip;","og_url":"https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/","og_site_name":"Justin&#039;s Blog","article_published_time":"2026-01-18T18:06:01+00:00","article_modified_time":"2026-01-18T18:06:03+00:00","og_image":[{"url":"https:\/\/justinmatters.co.uk\/wp\/wp-content\/uploads\/2026\/01\/UV-700x233.png","type":"","width":"","height":""}],"author":"justinmatters","twitter_card":"summary_large_image","twitter_misc":{"Written by":"justinmatters","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/#article","isPartOf":{"@id":"https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/"},"author":{"name":"justinmatters","@id":"https:\/\/justinmatters.co.uk\/wp\/#\/schema\/person\/7c3e0740e1fef74f705c19f175f6f321"},"headline":"Using UV for Python Package Management","datePublished":"2026-01-18T18:06:01+00:00","dateModified":"2026-01-18T18:06:03+00:00","mainEntityOfPage":{"@id":"https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/"},"wordCount":663,"commentCount":0,"image":{"@id":"https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/#primaryimage"},"thumbnailUrl":"https:\/\/justinmatters.co.uk\/wp\/wp-content\/uploads\/2026\/01\/UV-700x233.png","keywords":["Environment","Packages","Python","UV"],"articleSection":["Data Science"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/","url":"https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/","name":"Using UV for Python Package Management - Justin&#039;s Blog","isPartOf":{"@id":"https:\/\/justinmatters.co.uk\/wp\/#website"},"primaryImageOfPage":{"@id":"https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/#primaryimage"},"image":{"@id":"https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/#primaryimage"},"thumbnailUrl":"https:\/\/justinmatters.co.uk\/wp\/wp-content\/uploads\/2026\/01\/UV-700x233.png","datePublished":"2026-01-18T18:06:01+00:00","dateModified":"2026-01-18T18:06:03+00:00","author":{"@id":"https:\/\/justinmatters.co.uk\/wp\/#\/schema\/person\/7c3e0740e1fef74f705c19f175f6f321"},"breadcrumb":{"@id":"https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/#primaryimage","url":"https:\/\/justinmatters.co.uk\/wp\/wp-content\/uploads\/2026\/01\/UV.png","contentUrl":"https:\/\/justinmatters.co.uk\/wp\/wp-content\/uploads\/2026\/01\/UV.png","width":1515,"height":504},{"@type":"BreadcrumbList","@id":"https:\/\/justinmatters.co.uk\/wp\/using-uv-for-python-package-management\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/justinmatters.co.uk\/wp\/"},{"@type":"ListItem","position":2,"name":"Using UV for Python Package Management"}]},{"@type":"WebSite","@id":"https:\/\/justinmatters.co.uk\/wp\/#website","url":"https:\/\/justinmatters.co.uk\/wp\/","name":"Justin's Blog","description":"Justin&#039;s Coding and Geek Blog","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/justinmatters.co.uk\/wp\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/justinmatters.co.uk\/wp\/#\/schema\/person\/7c3e0740e1fef74f705c19f175f6f321","name":"justinmatters","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/27cf337940887c098b79716aa7025ce782bd51de3f6b07a9dcad710bbf576c59?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/27cf337940887c098b79716aa7025ce782bd51de3f6b07a9dcad710bbf576c59?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/27cf337940887c098b79716aa7025ce782bd51de3f6b07a9dcad710bbf576c59?s=96&d=mm&r=g","caption":"justinmatters"},"description":"Data Scientist specialising in Python, PySpark, SQL and Machine Learning","sameAs":["https:\/\/justinmatters.co.uk\/wp\/","https:\/\/uk.linkedin.com\/in\/justin-matters-edinburgh"]}]}},"_links":{"self":[{"href":"https:\/\/justinmatters.co.uk\/wp\/wp-json\/wp\/v2\/posts\/1648","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/justinmatters.co.uk\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/justinmatters.co.uk\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/justinmatters.co.uk\/wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/justinmatters.co.uk\/wp\/wp-json\/wp\/v2\/comments?post=1648"}],"version-history":[{"count":13,"href":"https:\/\/justinmatters.co.uk\/wp\/wp-json\/wp\/v2\/posts\/1648\/revisions"}],"predecessor-version":[{"id":1662,"href":"https:\/\/justinmatters.co.uk\/wp\/wp-json\/wp\/v2\/posts\/1648\/revisions\/1662"}],"wp:attachment":[{"href":"https:\/\/justinmatters.co.uk\/wp\/wp-json\/wp\/v2\/media?parent=1648"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/justinmatters.co.uk\/wp\/wp-json\/wp\/v2\/categories?post=1648"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/justinmatters.co.uk\/wp\/wp-json\/wp\/v2\/tags?post=1648"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}