Terminal — the command line

The terminal is the interface that everything else runs through. Git, npm, Node.js, deployment tools — they all live here. You don't need to memorize everything. You need to understand the logic and know where to look.

What is the terminal?

The terminal (also called the command line, shell, or CLI — command line interface) is a text-based way to control your computer. Instead of clicking icons, you type commands.

On Mac, it's the Terminal app (or iTerm2). On Linux, it's your default terminal emulator. On Windows, it's PowerShell or Windows Terminal running Git Bash or WSL.

You use the terminal because most developer tools only have a command-line interface — no GUI. Git, npm, Node.js, deployment tools, cloud CLIs — they're all terminal-first.

Where are you? Navigating the file system

The terminal always has a "current location" — the folder you're working in. These commands help you navigate:

CommandWhat it doesWhy you use it
pwdPrint Working Directory — shows your current folder pathKnow exactly where you are
lsList files and folders in the current directorySee what's here
ls -laList all files including hidden ones, with detailsSee hidden files (like .env) and permissions
cd foldernameChange Directory — move into a folderNavigate into a project folder
cd ..Move up one level (to parent folder)Go back up in the directory tree
cd ~Go to your home directoryQuick reset to your user folder
cd -Go back to the previous directoryToggle between two locations
Navigating to a project
pwd
# /Users/alex

cd Documents/projects/my-app
pwd
# /Users/alex/Documents/projects/my-app

ls
# index.js  package.json  node_modules/  src/

Creating and deleting

CommandWhat it doesWhy you use it
mkdir nameMake Directory — create a new folderSet up project folders
mkdir -p a/b/cCreate nested folders all at onceCreate a deep folder structure in one command
touch file.txtCreate an empty fileQuickly create a new file
rm file.txtRemove a file permanentlyDelete a file (no Trash — gone immediately)
rm -rf folder/Remove a folder and everything inside itDelete a whole directory — be careful
cp a.txt b.txtCopy a fileDuplicate a file
mv a.txt b.txtMove or rename a fileRename files or move them to a different folder
rm -rf is permanent. There is no Trash. If you delete something with rm, it's gone. Double-check before running it, especially with -rf.

Reading files in the terminal

CommandWhat it doesWhy you use it
cat file.txtPrint the entire file to the terminalQuickly read a short file
head -n 20 file.txtShow the first 20 linesPreview the top of a large file
tail -n 20 file.txtShow the last 20 linesCheck recent log file entries
tail -f file.logFollow a file as it growsWatch live server logs
grep "error" file.logSearch for a pattern in a fileFind errors in log files quickly

Clearing the terminal

Terminal housekeeping
clear          # Clear the terminal screen
history        # Show all past commands
history | grep npm  # Search your command history for npm commands

Keyboard shortcuts you'll use constantly:

  • ↑ / ↓ arrow keys — scroll through previous commands
  • Ctrl+C — stop the currently running process (stop a Node.js server, cancel a command)
  • Ctrl+L — clear the terminal (same as clear)
  • Tab — autocomplete file names and folder names

Pipes — chaining commands

A pipe (|) takes the output of one command and feeds it as input to another command. This lets you chain commands together to do more powerful things:

Pipe examples
# Find all .js files, then count them
ls *.js | wc -l

# Show running processes, search for "node"
ps aux | grep node

# Read a log file, filter for errors, show last 10
cat server.log | grep "ERROR" | tail -n 10

# List packages, search for express
npm list | grep express

Redirection — saving output to files

Redirect output to a file
# Write output to a file (overwrites)
echo "Hello World" > greeting.txt

# Append output to a file (adds to end)
echo "Another line" >> greeting.txt

# Save command output to a file
npm list > packages.txt

# Redirect error output to a file
node app.js 2> errors.log

# Redirect both output and errors
node app.js > output.log 2>&1

&& and || — conditional chaining

Run commands conditionally
# Run the second command ONLY if the first succeeds
npm run build && npx wrangler pages deploy dist

# Run the second command ONLY if the first fails
npm install || echo "npm install failed, check your network"

# Chain multiple commands that must all succeed
git add . && git commit -m "update" && git push

&& is the most useful one — it stops the chain if any command fails. So npm run build && deploy won't try to deploy if the build fails.

Environment variables in the terminal

Working with env vars
# Set a variable for this terminal session only
export MY_VAR=hello

# Use it
echo $MY_VAR

# Set a variable just for one command
NODE_ENV=production node server.js

# See all current environment variables
env

# Check one specific variable
echo $NODE_ENV

Finding things

Search commands
# Find files by name
find . -name "*.json"
find . -name ".env"

# Search file content for a string
grep -r "API_KEY" .
grep -r "DATABASE_URL" . --include="*.js"

# Find where a command is installed
which node
which npm

Shell profile — persistent configuration

Every time you open a terminal, it loads a configuration file. For bash it's ~/.bashrc or ~/.bash_profile. For zsh (default on Mac) it's ~/.zshrc.

~/.zshrc — common customizations
# Aliases — shortcuts for long commands
alias ll="ls -la"
alias gs="git status"
alias gp="git push"
alias ni="npm install"
alias nr="npm run"

# Add to PATH — so new CLIs are found
export PATH="$HOME/.local/bin:$PATH"

# Persistent environment variable
export EDITOR=nano

# After editing .zshrc, reload it:
source ~/.zshrc

Shell scripts

You can write a .sh file containing a sequence of commands and run it as a script:

deploy.sh
#!/bin/bash
# The #!/bin/bash tells the OS which interpreter to use

echo "Building..."
npm run build

echo "Deploying..."
npx wrangler pages deploy dist --project-name my-project

echo "Done."
Make it executable, then run it
chmod +x deploy.sh   # Grant execute permission (once)
./deploy.sh          # Run it

Process management

Managing processes
# Run a process in the background
node server.js &

# See all running processes
ps aux

# Kill a process by ID
kill 12345

# Kill all Node.js processes
pkill node

# Find what's using port 3000
lsof -i :3000

# Kill whatever is on port 3000
lsof -ti :3000 | xargs kill
The lsof -ti :3000 | xargs kill command is invaluable when you get EADDRINUSE: port 3000 already in use — it kills whatever process is holding that port.