Package managers like npm help you use code libraries built by other developers, while version control systems like Git track changes and enable safe collaboration.
| Tool | Without It | With It |
|---|---|---|
| npm(Package Manager) | Manually download librariesCopy-paste code into projectStruggle to update versionsNo version tracking | Install thousands of libraries (one command)Auto-manage dependenciesEasy updatesShare exact versions with team |
| Git(Version Control) | Files named project_v1.js, project_FINAL_ACTUALLY.jsLose track of changesFear breaking working codeOverwrite teammates' work |
Track every change with messagesRewind to any version instantlyExperiment fearlessly with branchesCollaborate seamlessly |
By the end of this lesson, you will:
package.json files confidentlynpm (Node Package Manager) is the default package manager for JavaScript.
Key Concepts:
express for web servers, axios for HTTP requests)Why npm matters:
# Install a package and add to dependencies
npm install axios
# Short version (same command)
npm i axios
# Install multiple packages at once
npm install express mongoose dotenv
What happens:
node_modules/ folderpackage.json to track the dependencypackage-lock.json to lock exact versionsSome packages are only needed during development (not in production):
# Install as dev dependency
npm install --save-dev nodemon
# Short version
npm i -D eslint prettier jest
Examples of dev dependencies:
nodemon - Auto-restart server on file changeseslint - Code quality checkerjest - Testing frameworkprettier - Code formatterWhy distinguish?
Example package.json:
{
"name": "spelling-bee-app",
"version": "1.0.0",
"description": "Interactive spelling game with AI integration",
"main": "index.js",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"test": "jest"
},
"dependencies": {
"express": "^4.18.2",
"axios": "^1.4.0",
"dotenv": "^16.3.1"
},
"devDependencies": {
"nodemon": "^3.0.1",
"jest": "^29.6.2"
},
"keywords": ["education", "spelling", "game"],
"author": "Your Name",
"license": "MIT"
}
Key sections explained:
| Field | Purpose | Example |
|---|---|---|
name |
Project identifier (lowercase, no spaces) | "spelling-bee-app" |
version |
Project version (MAJOR.MINOR.PATCH) | "1.0.0" |
description |
Brief project summary | "Interactive spelling game" |
main |
Entry point file | "index.js" |
scripts |
Custom commands you can run | "start": "node server.js" |
dependencies |
Packages needed in production | "express": "^4.18.2" |
devDependencies |
Packages only for development | "nodemon": "^3.0.1" |
keywords |
Searchable tags | ["education", "game"] |
license |
Code usage license | "MIT" |
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"test": "jest --coverage",
"lint": "eslint .",
"format": "prettier --write ."
}
Running scripts:
# Run the "start" script
npm start
# Run the "dev" script
npm run dev
# Run the "test" script
npm test
# Run custom scripts (need "run")
npm run lint
npm run format
💡 Tip: Use
npm runto see all available scripts in your project.
Critical Rule: NEVER COMMIT node_modules
Why?
npm installHow to exclude from Git:
Create a .gitignore file in your project root:
# .gitignore
node_modules/
.env
.DS_Store
When sharing your project:
package.json and package-lock.jsonnpm installnode_modules generates automaticallynpm packages use semantic versioning: MAJOR.MINOR.PATCH
Format: X.Y.Z
1.4.7
↑ ↑ ↑
│ │ └─ PATCH: Bug fixes (backwards compatible)
│ └─── MINOR: New features (backwards compatible)
└───── MAJOR: Breaking changes (NOT backwards compatible)
Examples:
| Version | Change Type | Description |
|---|---|---|
1.0.0 -> 1.0.1 |
Patch | Fixed a bug, safe to update |
1.0.1 -> 1.1.0 |
Minor | Added new feature, safe to update |
1.1.0 -> 2.0.0 |
Major | Changed API, READ CHANGELOG! |
Symbols control which updates are allowed:
| Symbol | Example | Allows Updates | Accepts | Blocks | Use When |
|---|---|---|---|---|---|
^(Caret)Default |
"express": "^4.18.2" |
MINOR + PATCH | 4.18.2 (exact)4.18.3 (patch)4.19.0 (minor) |
5.0.0 (major) |
You want new features and bug fixes automatically |
~(Tilde) |
"axios": "~1.4.0" |
PATCH only | 1.4.0 (exact)1.4.1 (patch) |
1.5.0 (minor)2.0.0 (major) |
You want only bug fixes, no new features |
| None(Exact) | "react": "18.2.0" |
No updates | 18.2.0 (exact only) |
18.2.1 (patch)18.3.0 (minor)19.0.0 (major) |
You need deterministic builds (rare) |
See installed versions:
# List all dependencies
npm list
# List top-level packages only
npm list --depth=0
# Check specific package
npm list axios
Output:
spelling-bee-app@1.0.0
├── axios@1.4.0
├── express@4.18.2
└── dotenv@16.3.1
Check for outdated packages:
npm outdated
Example output:
Package Current Wanted Latest Location
express 4.18.2 4.18.5 4.19.0 node_modules/express
axios 1.4.0 1.4.3 1.6.0 node_modules/axios
Interpretation:
package.json rangeUpdate packages:
# Update to "Wanted" versions (safe)
npm update
# Update specific package
npm update express
# Update to "Latest" (may break things!)
npm install express@latest
Sometimes packages have conflicting dependency requirements.
Common error:
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^18.0.0" from react-dom@18.2.0
Solution 1: Use --legacy-peer-deps
npm install --legacy-peer-deps
What it does: Ignores peer dependency conflicts (uses older resolution algorithm).
When to use:
💡 Note: npm 11.6.2 (latest as of 2025) includes an improved dependency resolver that handles conflicts better than older versions. If you encounter persistent dependency issues, ensure you're running
npm --version>= 11.0.
Solution 2: Use --force
npm install --force
What it does: Forces installation despite conflicts.
Warning: May cause runtime errors. Use cautiously!
Solution 3: Check npm version
Some projects require older npm versions:
# Check your npm version
npm --version
# Update npm
npm install -g npm@latest
# Use specific npm version (with nvm)
nvm use 16
Git saves snapshots of your code, enabling you to track changes and revert to previous versions.
# Turn current folder into a Git repository
git init
What happens:
.git folderWhen to use: Starting a new project.
git status
Example output:
On branch main
Changes not staged for commit:
modified: script.js
modified: style.css
Untracked files:
newfile.js
Interpretation:
main)When to use: Before committing to see what changed.
# Stage specific file
git add script.js
# Stage multiple files
git add script.js style.css
# Stage all changes (use carefully!)
git add .
# Stage all JavaScript files
git add *.js
What staging means:
# Commit with message
git commit -m "Add difficulty selector to spelling game"
# Commit with detailed message
git commit -m "Add difficulty selector" -m "Users can now choose Easy, Medium, or Hard modes. Each mode filters words by difficulty level."
# Stage and commit in one command
git commit -am "Fix typo in instructions"
What a commit does:
Switch to an existing branch:
# Modern way (Git 2.23+)
git switch main
# Traditional way (still works)
git checkout main
Create and switch to a new branch:
# Modern way
git switch -c feature-difficulty-selector
# Traditional way
git checkout -b feature-difficulty-selector
Restore (discard) changes to a file:
# Modern way
git restore script.js
# Traditional way
git checkout -- script.js
Why the new commands?
git switch handles branches only (clearer intent)git restore handles file changes only (safer)git checkout did both, which was confusing💡 Tip: Use modern commands for clarity. If you see
git checkoutin tutorials, translate:checkout <br />anch>->switch <br />anch>,checkout -- <file>->restore <file>.
git commit -m "fixed stuff"
git commit -m "update"
git commit -m "wip"
git commit -m "asdfasdf"
Why bad?
Good Commit Messages:
git commit -m "Add difficulty selector with Easy/Medium/Hard options"
git commit -m "Fix bug where hints deducted points twice"
git commit -m "Refactor word filtering to improve performance"
git commit -m "Update README with installation instructions"
Qualities of good messages:
Conventional Commits Format:
Many teams use standardized prefixes:
feat: Add user authentication
fix: Resolve crash on empty input
docs: Update API documentation
style: Format code with Prettier
refactor: Simplify scoring algorithm
test: Add unit tests for word filtering
chore: Update dependencies
Benefits:
Commit frequency guide:
✅ Good times to commit:
❌ Don't commit:
console.log statements everywhereGolden Rule: Commit working code frequently. Each commit should leave your project in a usable state.
# See all commits
git log
# Compact one-line view
git log --oneline
# Last 5 commits
git log -5
# Commits by specific author
git log --author="Your Name"
Example output:
commit a3f2b1c (HEAD -> main)
Author: Your Name <you@example.com>
Date: Thu Nov 6 10:30:00 2024
Add difficulty selector with Easy/Medium/Hard options
commit d4e5f6g
Author: Your Name <you@example.com>
Date: Thu Nov 6 09:15:00 2024
Fix bug where hints deducted points twice
You: "I need to make HTTP requests in my Node.js project.
What's the most popular package for this?"
AI: "The most popular package is **axios**. It's easier to
use than the built-in `fetch` and has excellent documentation.
Install with:
npm install axios
Basic usage:
const axios = require('axios');
const response = await axios.get('https://api.example.com/data');
console.log(response.data);
"
You: "I'm getting this npm error: [paste error message]
How do I fix it?"
AI: "This is a peer dependency conflict. Try:
npm install --legacy-peer-deps
This happens because react-router-dom expects React 18 but you
have React 17 installed. You can either:
1. Update React: npm install react@18
2. Use legacy mode: npm install --legacy-peer-deps
"
You: "What does this line mean in package.json?
"lodash": "^4.17.21""
AI: "The caret (^) means npm will install:
- Version 4.17.21 (exact match)
- Any newer MINOR or PATCH version (4.18.0, 4.17.22, etc.)
- But NOT version 5.0.0 (major version change)
This is safe because minor updates add features without
breaking existing code."
You: "I just added a difficulty selector, fixed a scoring bug,
and updated the README. Generate a commit message."
AI: "Since you made multiple unrelated changes, you should create
separate commits:
Commit 1:
git add difficulty-selector.js
git commit -m "feat: Add difficulty selector with Easy/Medium/Hard modes"
Commit 2:
git add scoring.js
git commit -m "fix: Prevent double point deduction on hints"
Commit 3:
git add README.md
git commit -m "docs: Update README with setup instructions"
"
You: "I got this error: 'fatal: not a git repository'
What does this mean?"
AI: "This means you're not in a Git-tracked folder.
Solutions:
1. If you want to track this folder:
git init
2. If you meant to work in a different folder:
cd path/to/your/project
git status
Check your current directory with: pwd
"
You: "Should I commit my node_modules folder?"
AI: "NO! Never commit node_modules.
Why?
- Huge size (100+ MB)
- Contains platform-specific files
- Can be regenerated with npm install
What to do:
1. Create .gitignore file
2. Add this line:
node_modules/
3. Commit the .gitignore:
git add .gitignore
git commit -m 'Add .gitignore to exclude node_modules'
Always commit package.json and package-lock.json instead!
"
You: "I keep seeing 'git checkout' in tutorials. Is there a better way?"
AI: "Yes! Git 2.23+ (2019) introduced clearer commands:
For switching branches:
# Old way
git checkout main
# New way (clearer)
git switch main
For discarding file changes:
# Old way
git checkout -- file.js
# New way (safer)
git restore file.js
Why change? git checkout did TWO different things (switch branches
AND restore files), which was confusing. The new commands separate
these concerns for clarity and safety.
Both ways still work, but modern commands prevent mistakes!"
1. Commit working code:
git commit -m "Checkpoint: game works perfectly"
2. Ask AI to refactor:
"Make this code more efficient"
3a. If AI's changes work:
git commit -m "Refactor scoring for performance"
3b. If AI breaks something:
git reset --hard HEAD (revert to checkpoint!)
The Git + AI Workflow:
NPM (Package Management):
npm install vs npm install --save-devpackage.json structure^ (caret) vs ~ (tilde)npm list, npm outdated--legacy-peer-depsGit (Version Control):
init, status, add, commitgit log --onelineAI Integration:
Before starting:
package.json.gitignore (exclude node_modules)During development:
When collaborating:
package.json, not node_modulesIn Activity 12, you'll practice these skills hands-on by setting up a project with npm and Git, then using AI to help you manage dependencies and commits!
💡 Remember: Package managers and version control aren't just technical tools - they're collaboration enablers. npm lets you build on others' work, while Git lets you work safely with teammates (including AI!).
The Professional Workflow:
git init - Start tracking your projectnpm init - Create package.jsonnpm install <package> - Add dependenciesgit add -> git commitWith AI:
Ready to practice? Let's move to Activity 12 where you'll set up a real project with npm and Git!