[{"data":1,"prerenderedAt":537},["ShallowReactive",2],{"blog-\u002Fblog\u002Fpython-virtual-environments-pip-explained":3},{"id":4,"title":5,"body":6,"description":523,"difficulty":524,"extension":525,"framework":526,"frameworkSlug":108,"meta":527,"navigation":376,"order":147,"path":528,"qaPath":529,"seo":530,"stem":531,"subtopic":532,"topic":533,"topicSlug":534,"updated":535,"__hash__":536},"blog\u002Fblog\u002Fpython-virtual-environments-pip-explained.md","Python Virtual Environments & pip Explained — venv, Dependency Isolation, and Reproducible Installs",{"type":7,"value":8,"toc":513},"minimark",[9,14,23,27,42,89,95,99,113,178,189,193,203,268,275,279,282,321,332,336,350,389,399,403,418,455,464,468,509],[10,11,13],"h2",{"id":12},"python-virtual-environments-pip-explained","Python virtual environments & pip, explained",[15,16,17,18,22],"p",{},"Install enough packages globally and two projects will eventually demand conflicting\nversions of the same library. Virtual environments solve this by giving each project its own\nisolated set of dependencies. Combined with ",[19,20,21],"code",{},"pip"," and a pinned requirements file, they make\ninstalls reproducible across machines.",[10,24,26],{"id":25},"the-problem-global-installs-collide","The problem: global installs collide",[15,28,29,30,33,34,37,38,41],{},"There's one system Python with one ",[19,31,32],{},"site-packages",". Install ",[19,35,36],{},"django==3"," for project A and\n",[19,39,40],{},"django==5"," for project B globally and one of them breaks — you can't have both at once.",[43,44,49],"pre",{"className":45,"code":46,"language":47,"meta":48,"style":48},"language-bash shiki shiki-themes github-light github-dark","pip install django==3      # project A needs this\npip install django==5      # ...now project A is broken\n","bash","",[19,50,51,74],{"__ignoreMap":48},[52,53,56,59,63,66,70],"span",{"class":54,"line":55},"line",1,[52,57,21],{"class":58},"sScJk",[52,60,62],{"class":61},"sZZnC"," install",[52,64,65],{"class":61}," django==",[52,67,69],{"class":68},"sj4cs","3",[52,71,73],{"class":72},"sJ8bj","      # project A needs this\n",[52,75,77,79,81,83,86],{"class":54,"line":76},2,[52,78,21],{"class":58},[52,80,62],{"class":61},[52,82,65],{"class":61},[52,84,85],{"class":68},"5",[52,87,88],{"class":72},"      # ...now project A is broken\n",[15,90,91,92,94],{},"Virtual environments give each project its own private ",[19,93,32],{},", so versions never\ncollide.",[10,96,98],{"id":97},"creating-and-activating-a-venv","Creating and activating a venv",[15,100,101,102,105,106,109,110,112],{},"The standard library's ",[19,103,104],{},"venv"," module creates an isolated environment — a folder with its own\nPython and package directory. Activating it points ",[19,107,108],{},"python"," and ",[19,111,21],{}," at that folder.",[43,114,116],{"className":45,"code":115,"language":47,"meta":48,"style":48},"python -m venv .venv            # create the environment\nsource .venv\u002Fbin\u002Factivate       # activate (Linux\u002FmacOS)\n# .venv\\Scripts\\activate        # Windows\npython -m pip install requests  # installs into .venv only\ndeactivate                      # leave the environment\n",[19,117,118,134,145,151,169],{"__ignoreMap":48},[52,119,120,122,125,128,131],{"class":54,"line":55},[52,121,108],{"class":58},[52,123,124],{"class":68}," -m",[52,126,127],{"class":61}," venv",[52,129,130],{"class":61}," .venv",[52,132,133],{"class":72},"            # create the environment\n",[52,135,136,139,142],{"class":54,"line":76},[52,137,138],{"class":68},"source",[52,140,141],{"class":61}," .venv\u002Fbin\u002Factivate",[52,143,144],{"class":72},"       # activate (Linux\u002FmacOS)\n",[52,146,148],{"class":54,"line":147},3,[52,149,150],{"class":72},"# .venv\\Scripts\\activate        # Windows\n",[52,152,154,156,158,161,163,166],{"class":54,"line":153},4,[52,155,108],{"class":58},[52,157,124],{"class":68},[52,159,160],{"class":61}," pip",[52,162,62],{"class":61},[52,164,165],{"class":61}," requests",[52,167,168],{"class":72},"  # installs into .venv only\n",[52,170,172,175],{"class":54,"line":171},5,[52,173,174],{"class":58},"deactivate",[52,176,177],{"class":72},"                      # leave the environment\n",[15,179,180,181,184,185,188],{},"Once activated, ",[19,182,183],{},"pip install"," affects only this project. The ",[19,186,187],{},".venv"," folder is disposable and\nshould be git-ignored — you recreate it from your requirements file.",[10,190,192],{"id":191},"how-pip-installs-packages","How pip installs packages",[15,194,195,197,198,202],{},[19,196,21],{}," downloads packages from ",[199,200,201],"strong",{},"PyPI"," (the Python Package Index) and installs them, along\nwith their dependencies, into the active environment.",[43,204,206],{"className":45,"code":205,"language":47,"meta":48,"style":48},"pip install requests            # latest compatible version\npip install \"django>=4,\u003C5\"      # a version range\npip install -e .                # editable install of the local project\npip list                        # what's installed\npip show requests               # details + dependencies\n",[19,207,208,219,231,246,256],{"__ignoreMap":48},[52,209,210,212,214,216],{"class":54,"line":55},[52,211,21],{"class":58},[52,213,62],{"class":61},[52,215,165],{"class":61},[52,217,218],{"class":72},"            # latest compatible version\n",[52,220,221,223,225,228],{"class":54,"line":76},[52,222,21],{"class":58},[52,224,62],{"class":61},[52,226,227],{"class":61}," \"django>=4,\u003C5\"",[52,229,230],{"class":72},"      # a version range\n",[52,232,233,235,237,240,243],{"class":54,"line":147},[52,234,21],{"class":58},[52,236,62],{"class":61},[52,238,239],{"class":68}," -e",[52,241,242],{"class":61}," .",[52,244,245],{"class":72},"                # editable install of the local project\n",[52,247,248,250,253],{"class":54,"line":153},[52,249,21],{"class":58},[52,251,252],{"class":61}," list",[52,254,255],{"class":72},"                        # what's installed\n",[52,257,258,260,263,265],{"class":54,"line":171},[52,259,21],{"class":58},[52,261,262],{"class":61}," show",[52,264,165],{"class":61},[52,266,267],{"class":72},"               # details + dependencies\n",[15,269,270,271,274],{},"Always run it as ",[19,272,273],{},"python -m pip"," when in doubt — it guarantees you're using the pip tied to\nthe Python you mean.",[10,276,278],{"id":277},"pinning-with-requirementstxt","Pinning with requirements.txt",[15,280,281],{},"To reproduce an environment elsewhere, freeze your installed versions to a file and install\nfrom it. This is what makes a build deterministic.",[43,283,285],{"className":45,"code":284,"language":47,"meta":48,"style":48},"pip freeze > requirements.txt   # snapshot exact versions\n# elsewhere:\npip install -r requirements.txt\n",[19,286,287,304,309],{"__ignoreMap":48},[52,288,289,291,294,298,301],{"class":54,"line":55},[52,290,21],{"class":58},[52,292,293],{"class":61}," freeze",[52,295,297],{"class":296},"szBVR"," >",[52,299,300],{"class":61}," requirements.txt",[52,302,303],{"class":72},"   # snapshot exact versions\n",[52,305,306],{"class":54,"line":76},[52,307,308],{"class":72},"# elsewhere:\n",[52,310,311,313,315,318],{"class":54,"line":147},[52,312,21],{"class":58},[52,314,62],{"class":61},[52,316,317],{"class":68}," -r",[52,319,320],{"class":61}," requirements.txt\n",[15,322,323,324,327,328,331],{},"A ",[19,325,326],{},"requirements.txt"," of pinned versions (",[19,329,330],{},"requests==2.31.0",") ensures every machine and CI run\ngets identical dependencies — no \"works on my machine\" surprises.",[10,333,335],{"id":334},"pyprojecttoml-and-dependency-groups","pyproject.toml and dependency groups",[15,337,338,339,344,345,349],{},"Modern projects declare dependencies in ",[199,340,341],{},[19,342,343],{},"pyproject.toml"," instead of (or alongside)\nrequirements files. It's the standard for packaging ",[346,347,348],"em",{},"and"," for specifying what your project\nneeds.",[43,351,355],{"className":352,"code":353,"language":354,"meta":48,"style":48},"language-toml shiki shiki-themes github-light github-dark","[project]\nname = \"myapp\"\ndependencies = [\"requests>=2.31\", \"rich\"]\n\n[project.optional-dependencies]\ndev = [\"pytest\", \"ruff\"]\n","toml",[19,356,357,362,367,372,378,383],{"__ignoreMap":48},[52,358,359],{"class":54,"line":55},[52,360,361],{},"[project]\n",[52,363,364],{"class":54,"line":76},[52,365,366],{},"name = \"myapp\"\n",[52,368,369],{"class":54,"line":147},[52,370,371],{},"dependencies = [\"requests>=2.31\", \"rich\"]\n",[52,373,374],{"class":54,"line":153},[52,375,377],{"emptyLinePlaceholder":376},true,"\n",[52,379,380],{"class":54,"line":171},[52,381,382],{},"[project.optional-dependencies]\n",[52,384,386],{"class":54,"line":385},6,[52,387,388],{},"dev = [\"pytest\", \"ruff\"]\n",[15,390,391,394,395,398],{},[19,392,393],{},"pip install ."," installs the runtime deps; ",[19,396,397],{},"pip install \".[dev]\""," adds the dev extras. This\nkeeps everything about the project in one declarative file.",[10,400,402],{"id":401},"faster-all-in-one-tooling","Faster, all-in-one tooling",[15,404,405,406,409,410,413,414,417],{},"Newer tools wrap environment + dependency management together. ",[199,407,408],{},"uv"," (and ",[199,411,412],{},"Poetry",",\n",[199,415,416],{},"pipenv",") create the venv, resolve and lock dependencies, and install — much faster than\nplain pip and with reproducible lockfiles.",[43,419,421],{"className":45,"code":420,"language":47,"meta":48,"style":48},"uv venv                 # create environment\nuv pip install requests # install into it\nuv lock                 # write an exact lockfile\n",[19,422,423,432,445],{"__ignoreMap":48},[52,424,425,427,429],{"class":54,"line":55},[52,426,408],{"class":58},[52,428,127],{"class":61},[52,430,431],{"class":72},"                 # create environment\n",[52,433,434,436,438,440,442],{"class":54,"line":76},[52,435,408],{"class":58},[52,437,160],{"class":61},[52,439,62],{"class":61},[52,441,165],{"class":61},[52,443,444],{"class":72}," # install into it\n",[52,446,447,449,452],{"class":54,"line":147},[52,448,408],{"class":58},[52,450,451],{"class":61}," lock",[52,453,454],{"class":72},"                 # write an exact lockfile\n",[15,456,457,458,460,461,463],{},"For new projects these are worth adopting; for understanding the fundamentals, ",[19,459,104],{}," + ",[19,462,21],{},"\nis exactly what they automate.",[10,465,467],{"id":466},"recap","Recap",[15,469,323,470,473,474,476,477,480,481,483,484,487,488,491,492,494,495,498,499,503,504,109,506,508],{},[199,471,472],{},"virtual environment"," gives each project its own isolated ",[19,475,32],{}," so dependency\nversions never collide — create one with ",[19,478,479],{},"python -m venv .venv",", activate it, and install\nfreely. ",[199,482,21],{}," fetches packages (and their dependencies) from PyPI into the active\nenvironment. Make installs reproducible by ",[199,485,486],{},"pinning"," versions (",[19,489,490],{},"pip freeze"," →\n",[19,493,326],{},", then ",[19,496,497],{},"pip install -r","), or declare them in ",[199,500,501],{},[19,502,343],{},". Modern\ntools like ",[199,505,408],{},[199,507,412],{}," bundle environment creation, locking, and installing into\none fast workflow.",[510,511,512],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}",{"title":48,"searchDepth":76,"depth":76,"links":514},[515,516,517,518,519,520,521,522],{"id":12,"depth":76,"text":13},{"id":25,"depth":76,"text":26},{"id":97,"depth":76,"text":98},{"id":191,"depth":76,"text":192},{"id":277,"depth":76,"text":278},{"id":334,"depth":76,"text":335},{"id":401,"depth":76,"text":402},{"id":466,"depth":76,"text":467},"Why Python projects need virtual environments and how to use them — creating venvs, how pip installs packages, pinning with requirements.txt, and modern tooling like pyproject.toml and uv.","easy","md","Python",{},"\u002Fblog\u002Fpython-virtual-environments-pip-explained","\u002Fpython\u002Fmodules\u002Fvirtual-environments",{"title":5,"description":523},"blog\u002Fpython-virtual-environments-pip-explained","Virtual Environments & pip","Modules, Packages & Environments","modules","2026-06-19","BUr0kPST0pqGPgdhOYvbfT9EdZcEFbX8kAB4u_jIYIg",1782244093577]