You've mastered the command line. You understand your operating system and your development environment. Now it's time to learn how modern developers leverage the work of others: through packages, registries, and package managers.
Everything that comes next—Claude Code, Docker, OpenClaw, web applications—builds on the concepts you're about to learn. And at the center of all of it is a simple idea: reusable code, stored in a central place, installed with a single command. This is where we leverage the power of the Internet and begin to see the open-source community come into play.
Let's start with the why, then move to the how.
What is a Package?
A package (also called a module or library) is a collection of reusable code that someone else wrote, tested, and shared. Instead of writing authentication from scratch, you install a package that handles it. Instead of building a web server from the ground up, you install a package that does it for you.
Packages can be:
- Small utilities: A function that formats dates, validates emails, or parses JSON
- Large frameworks: Complete systems for building web applications, managing databases, or running AI agents
- Tools and CLIs: Command-line applications you run directly
What Problem Do Registries Solve?
Before registries, developers had to email code to each other, host code on personal websites, track versions manually, and hope dependencies didn't break. A registry is a centralized, organized library where developers can publis* packages and others can install them. Think of it like an app store, but for code.
The most famous registry nowadays is the NPM Registry—the default home for JavaScript/Node.js packages. But the pattern appears everywhere:
- Docker Hub — Registry for container images
- PyPI — Registry for Python packages
- ClawHub — Registry for OpenClaw AI agent configurations
What About GitHub?
GitHub isn't a registry for packages, but it plays a similar role and is crucial in the ecosystem: it’s a code repository hosting platform (one of several) where developers store their source code using Git version control. Most open-source packages (NPM, Docker, etc.) have their source code hosted on GitHub. Developers also collaborate on code through GitHub. And, while you can also install packages directly from GitHub repos (npm install github:username/repo), you'll also be able to clone many GitHub code repositories that are not packages, such as apps and projects. Like package registries, it's a vital way to build on the success of others.
How Registries Work
Here's the flow:
- Developer writes code (e.g., a useful function)
- Developer publishes to registry with a version number and metadata
-
You install from registry with a single command:
npm install package-name - Registry delivers the code to your project
- You use the code in your application
That's it. The registry is the middleman—a trusted place where packages live, versions are tracked, and installation is automatic.
Risks You Need to Know
Registries are powerful, but they come with responsibilities:
1. Security Vulnerabilities
Packages can have bugs or security holes. A popular package with a vulnerability could affect thousands of projects. Always:
- Keep packages updated (
npm update) - Check package reputation before installing
- Use
npm auditto find known vulnerabilities
2. Unmaintained Packages
A developer might stop maintaining a package. If it breaks or has a security issue, you're on your own. Check:
- When was the last update?
- Is the repository active?
- How many people use it? (Popular = more eyes, more fixes)
3. Breaking Changes
New versions of packages might not work with your code. A seemingly small update could break your entire application. This is why versioning matters (we'll cover this below).
4. Supply Chain Risk
If you install 10 packages, and each installs 5 more, you're now depending on 50+ packages. One vulnerability in any of them affects you. Be intentional about what you install.
Further down we'll cover how to audit your packages.
How Packages Are Versioned
Packages use semantic versioning (semver): MAJOR.MINOR.PATCH
Example: 1.2.3
- 1 (major) — Breaking changes. Code might not work.
- 2 (minor) — New features, but backwards compatible.
- 3 (patch) — Bug fixes only, always safe.
When you install a package, you specify which versions you're willing to accept:
-
1.2.3— Exactly this version -
^1.2.3— Any version up to2.0.0(minor and patch updates okay) -
~1.2.3— Any version up to1.3.0(patch updates only) -
*orlatest— Always the newest (risky!)
Your package.json file tracks this, ensuring your project stays reproducible.
What is Node.js?
JavaScript is one of the most accessible and widely-used programming languages. It's forgiving and relatively easy to learn. For decades, it only ran in browsers. Then Node.js arrived in 2009. Node.js is a JavaScript runtime environment. It lets you run JavaScript on your computer, on servers, and in development tools.
This means you can write or download JavaScript scripts and applications that run on your machine -- some as CLIs.
Result: NPM (Node Package Manager) is now the largest package registry in the world (over 2 million packages). JavaScript developers could write reusable code once and share it. That accessibility cascaded into an ecosystem. This is why you'll see Node.js/JavaScript everywhere in development tools—from build systems to CLI tools to web servers.
Installing Node.js and NPM
Node.js and NPM come together. When you install Node.js, you automatically get NPM.
Download and install nvm:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash
In lieu of restarting the shell:
\. "$HOME/.nvm/nvm.sh"
Download and install Node.js:
nvm install 24
Verify the Node.js version:
node -v # Should print "v24.16.0".
Verify npm version:
npm -v # Should print "11.13.0".
The above works on WSL and macOS (even though it says
bash). However, the version numbers above may become outdated; refer to the page below for the current version.
Creating a Project: npm init
We're not quite getting into projects yet, but when you start a new project, you initialize it with NPM:
mkdir my-project
cd my-project
npm init
NPM asks questions about your project (name, description, author, etc.). Answer them or press Enter to accept defaults. This creates package.json — the most important file in your project.
Understanding package.json
package.json is the contract for your project. It tells others (and future you):
- What your project is
- What dependencies it needs
- What scripts it can run
- What version it is
Example:
{
"name": "my-project",
"version": "1.0.0",
"description": "My awesome project",
"main": "index.js",
"scripts": {
"start": "node index.js",
"build": "echo Building...",
"test": "echo Running tests..."
},
"dependencies": {
"express": "^4.18.0",
"axios": "^1.4.0"
},
"devDependencies": {
"nodemon": "^2.0.20"
}
}
Key sections:
-
scripts— Commands you can run (npm start,npm run build) -
dependencies— Packages your project needs to run -
devDependencies— Packages you only need during development (testing, build tools, etc.)
Installing Packages
Install a package with:
npm install express
This:
- Downloads
expressfrom NPM Registry - Adds it to
dependenciesinpackage.json - Creates
node_modules/folder (contains the actual code) - Creates
package-lock.json(locks exact versions for reproducibility)
Install a development-only package:
npm install --save-dev nodemon
This adds it to devDependencies instead.
Understanding node_modules
When you install packages, NPM creates a node_modules/ folder. This folder contains:
- The package you installed
- All of its dependencies
- All of their dependencies
- And so on...
It can get HUGE (hundreds of MB).
- Always commit
package.jsonandpackage-lock.jsonto Git. - Never commit
node_modules/— it's too large, so it should be in your.gitignore. - When someone clones your project, they run
npm installand it rebuildsnode_modulesfrompackage.json.
Updating Packages
Check for outdated packages:
npm outdated
Update packages to their latest versions (respecting semver rules):
npm update
Update a specific package:
npm install express@latest
Caution: Updating can introduce breaking changes. Always test after updating, and commit your work first so you can revert if needed.
Running Scripts
You define scripts in package.json:
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"build": "webpack",
"test": "jest"
}
Run them with:
npm start
npm run dev
npm run build
npm test
Scripts are shortcuts. npm start is the same as running the command specified. This is why they're powerful—you can hide complex commands behind simple names.
How Can I Audit My Packages for Security/Bugs?
Security vulnerabilities in packages are inevitable. The good news: tools exist to help you manage them.
Manual audits with npm CLI:
When you're working in your project locally, you can run npm audit to check for known vulnerabilities in your packages. It scans against a database of known issues and suggests fixes. This is a manual check you do when you remember to do it.
Continuous monitoring (future):
When you later learn about version control with GitHub, you'll discover a tool called Dependabot that works alongside your package manager. Here's the idea:
- Your package manager (NPM) handles installation and updates
- Your code hosting platform (GitHub) can monitor your packages continuously
- Dependabot automatically scans for vulnerabilities, notifies you of issues, and suggests updates
- It never sleeps—it's checking your dependencies while you work on other things
This is an example of how tools in the ecosystem work together: one tool for packages, another for monitoring. You'll see this pattern throughout development—specialized tools doing specific jobs, all integrated together.
For now: Just know that security monitoring exists and is important. When you start working with version control and GitHub, you'll see how these tools connect.
Tools Worth Knowing About
nvm — Node Version Manager
nvm install 18
nvm use 18
Manage multiple Node.js versions. Useful when different projects need different versions.
npx — Run packages without installing globally
npx create-react-app my-app
Downloads and runs a package once, without installing it permanently. Great for one-off tools and generators.
Yarn — Alternative to NPM
yarn install
yarn add express
Different package manager with similar features. Some developers prefer it. For now, stick with NPM—they work the same way conceptually.
Registries: A Pattern You'll See Everywhere
Here's the crucial connection:
NPM Registry is a registry of packages (JavaScript code).
Docker Hub is a registry of images (containerized applications).
ClawHub is a registry of AI skills for OpenClaw.
The pattern is identical:
- Someone creates something useful
- They publish it to a registry with metadata and versioning
- You install it with a command
- You use it in your work
You now understand:
- What packages are and why they matter
- How registries work as central libraries
- The risks and how to manage them
- How to use NPM and manage dependencies
- That this pattern repeats everywhere
Next we'll get into AI.
Sources / additional material:
https://docs.npmjs.com/cli/v9/configuring-npm/package-json
https://semver.org/ — Semantic Versioning specification
https://docs.npmjs.com/downloading-and-installing-packages-locally
This article was generated with AI for the purpose of providing practical information. I have reviewed it and edited it appropriately.
Top comments (0)