📦Package Managers & Installing Software
Install Node.js, Python, and developer tools from the command line
What Is a Package Manager?
Think of a package manager as an app store for your terminal. Instead of opening a browser, searching for software, downloading an installer, and clicking "Next" five times, you type one command and the tool handles everything — downloading, verifying, installing, and configuring.
Every modern operating system and programming language has at least one package manager. Mastering them is one of the fastest ways to become productive on the command line.
Why Package Managers Matter
- Speed — install software in seconds, not minutes.
- Reproducibility — share a single file (
package.json,requirements.txt) and anyone can recreate your exact environment. - Security — packages are verified with checksums; updates are one command away.
- Automation — scripts and CI/CD pipelines rely on package managers to set up environments without human interaction.
System-Level Package Managers
These install programs globally on your computer — command-line tools, libraries, even full applications.
Homebrew (macOS & Linux)
Homebrew is the most popular package manager for macOS. It also works on Linux.
# Install Homebrew (one-time setup)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Search for a package
brew search node
# Install a package
brew install node
# See what is installed
brew list
# Update Homebrew itself and all package definitions
brew update
# Upgrade all installed packages to their latest versions
brew upgrade
# Upgrade a specific package
brew upgrade node
# Remove a package
brew uninstall node
# Check for problems
brew doctorTip: Homebrew also supports
brew install --caskfor GUI applications like VS Code, Firefox, or Docker Desktop.
apt (Debian / Ubuntu Linux)
apt is the default package manager on Debian-based Linux distributions such
as Ubuntu.
# Update the list of available packages
sudo apt update
# Install a package
sudo apt install nodejs
# Upgrade all installed packages
sudo apt upgrade
# Remove a package
sudo apt remove nodejs
# Search for a package
apt search nodejs
# Show package details
apt show nodejsNote: On Linux you often need
sudo(superuser) because system packages are installed into protected directories like/usr/bin.
Windows Package Managers
Windows has two popular options:
winget (built into Windows 11 and recent Windows 10 builds):
winget search nodejs
winget install OpenJS.NodeJS
winget upgrade --allChocolatey (community-driven, widely used):
choco install nodejs
choco upgrade all
choco list --local-onlyComparison of System Package Managers
| Feature | Homebrew (macOS) | apt (Linux) | winget (Windows) | Chocolatey (Windows) |
|---|---|---|---|---|
| Install cmd | brew install | sudo apt install | winget install | choco install |
| Update list | brew update | sudo apt update | automatic | automatic |
| Upgrade all | brew upgrade | sudo apt upgrade | winget upgrade --all | choco upgrade all |
| GUI apps | --cask flag | varies | yes | yes |
| Needs sudo | no | yes | no | yes (admin) |
Installing Essential Developer Tools
Installing Git
# macOS (comes pre-installed, but you can get the latest)
brew install git
# Ubuntu / Debian
sudo apt install git
# Windows
winget install Git.Git
# Verify the installation
git --versionInstalling Node.js (nvm Recommended)
You can install Node.js directly with a system package manager, but the recommended way is through nvm (Node Version Manager). This lets you switch between Node versions per project.
# Install nvm (macOS / Linux)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# Restart your terminal, then:
nvm install --lts # install the latest LTS version
nvm install 20 # install a specific major version
nvm use 20 # switch to Node 20
nvm ls # list installed versions
nvm alias default 20 # set the default version
# Verify
node --version
npm --versionWhy nvm? Different projects may need different Node versions. nvm lets you switch instantly without breaking anything.
Installing Python
Most systems ship with Python, but you may need to manage multiple versions.
# macOS
brew install python
# Ubuntu / Debian
sudo apt install python3 python3-pip python3-venv
# Windows
winget install Python.Python.3.12
# Verify
python3 --version
pip3 --versionFor version management similar to nvm, look at pyenv.
Language-Level Package Managers
System package managers install tools on your machine. Language-level package managers install libraries and dependencies for a specific programming language inside a project.
npm — Node.js Package Manager
npm is installed automatically when you install Node.js. It manages JavaScript and TypeScript packages.
# Start a new project (creates package.json)
npm init -y
# Install a package as a dependency
npm install express
# Install a package as a dev dependency
npm install --save-dev typescript
# Install all dependencies listed in package.json
npm install
# Run a script defined in package.json
npm run build
npm run dev
npm test
# Run a package without installing it globally
npx create-next-app my-app
# Remove a package
npm uninstall express
# See outdated packages
npm outdated
# Update packages
npm updateUnderstanding package.json
package.json is the heart of any Node.js project. Here is a simplified
example:
{
"name": "my-app",
"version": "1.0.0",
"description": "A sample application",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"build": "tsc",
"test": "jest"
},
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"typescript": "^5.3.0",
"nodemon": "^3.0.0",
"jest": "^29.7.0"
}
}Key sections:
- name / version — identity of your project.
- scripts — custom commands you run with
npm run <name>. - dependencies — packages your app needs to run in production.
- devDependencies — packages needed only during development (testing, building, linting).
The
^symbol means "compatible with".^4.18.2allows updates like4.18.3or4.19.0but not5.0.0.
pip — Python Package Manager
pip installs Python packages from the Python Package Index (PyPI).
# Install a package
pip install requests
# Install a specific version
pip install requests==2.31.0
# Install from a requirements file
pip install -r requirements.txt
# List installed packages
pip list
# Freeze current packages into a file (for sharing)
pip freeze > requirements.txt
# Uninstall a package
pip uninstall requests
# Upgrade a package
pip install --upgrade requestsUnderstanding requirements.txt
This is Python's equivalent of package.json for listing dependencies:
requests==2.31.0
flask==3.0.0
sqlalchemy>=2.0.0,<3.0.0
python-dotenv~=1.0.0
Each line lists a package and optional version constraints.
Global vs Local Packages
This is one of the most confusing topics for beginners. Here is the rule:
| Scope | Where it lives | When to use |
|---|---|---|
| Global | System-wide (e.g. /usr/local) | CLI tools you use everywhere |
| Local | Inside the project folder | Libraries specific to this project |
npm example:
# Global — available everywhere (use sparingly)
npm install -g typescript
# Local — installed into ./node_modules (preferred)
npm install typescript --save-devpip example:
# Global — installs into the system Python
pip install black
# Local — use a virtual environment (preferred)
python3 -m venv .venv
source .venv/bin/activate # now pip installs into .venv
pip install blackBest practice: keep packages local whenever possible. Global installs can conflict across projects.
Virtual Environments (Python)
A virtual environment is an isolated Python installation inside your project folder. It prevents version conflicts between projects.
# Create a virtual environment
python3 -m venv .venv
# Activate it (macOS / Linux)
source .venv/bin/activate
# Activate it (Windows PowerShell)
.\.venv\Scripts\Activate.ps1
# Your prompt changes to show the active environment
(.venv) $
# Now pip installs into .venv, not globally
pip install flask
# Deactivate when you are done
deactivateTypical workflow:
- Clone a project.
- Create a virtual environment:
python3 -m venv .venv - Activate it:
source .venv/bin/activate - Install dependencies:
pip install -r requirements.txt - Work on the project.
- When finished:
deactivate
Tip: Add
.venv/to your.gitignoreso the virtual environment is never committed to version control.
Comparison of Language Package Managers
| Feature | npm (Node.js) | pip (Python) |
|---|---|---|
| Config file | package.json | requirements.txt |
| Lock file | package-lock.json | pip freeze output |
| Install all deps | npm install | pip install -r req.txt |
| Add a package | npm install pkg | pip install pkg |
| Dev dependencies | --save-dev flag | separate file or extras |
| Run scripts | npm run <script> | manual or Makefile |
| Run without install | npx <command> | pipx run <command> |
| Isolation | node_modules per project | virtual environments |
| Version manager | nvm | pyenv |
Common Workflows
Starting a New Node.js Project
mkdir my-project && cd my-project
npm init -y
npm install express
npm install --save-dev nodemonStarting a New Python Project
mkdir my-project && cd my-project
python3 -m venv .venv
source .venv/bin/activate
pip install flask
pip freeze > requirements.txtSetting Up a Cloned Project (Node.js)
git clone https://github.com/user/repo.git
cd repo
npm install # reads package.json and installs everything
npm run dev # start the dev serverSetting Up a Cloned Project (Python)
git clone https://github.com/user/repo.git
cd repo
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python app.pyTroubleshooting Common Issues
| Problem | Solution |
|---|---|
command not found: brew | Reinstall Homebrew or add it to your PATH |
permission denied with npm global | Use nvm instead of sudo; avoid sudo npm |
| Wrong Node version in a project | Use nvm use or add an .nvmrc file |
| pip installs into wrong Python | Always activate your virtual environment first |
node_modules is huge | Normal — never commit it; add to .gitignore |
| Conflicting package versions | Delete node_modules and npm install again |
Quick Reference Cheat Sheet
# ── System tools ──
brew install <pkg> # macOS install
sudo apt install <pkg> # Linux install
winget install <pkg> # Windows install
# ── Node.js ──
nvm install --lts # install latest Node LTS
npm init -y # new project
npm install <pkg> # add dependency
npm run <script> # run a script
npx <cmd> # run without installing
# ── Python ──
python3 -m venv .venv # create virtual env
source .venv/bin/activate # activate it
pip install <pkg> # add dependency
pip freeze > requirements.txt # save dependencies
deactivate # exit virtual envKey Takeaways
- Package managers save time — one command instead of manual downloads.
- System managers (Homebrew, apt, winget) install tools on your machine.
- Language managers (npm, pip) install libraries inside a project.
- Use nvm for Node.js and virtual environments for Python to avoid version conflicts.
- Prefer local installs over global ones for project-specific packages.
- Share your dependencies via
package.jsonorrequirements.txtso others can reproduce your setup.