Skip to content
Browse files
Initial drop. Ugly, sketchy, and not even yet quite a "work in progre…
  • Loading branch information
isaacs committed Sep 29, 2009
0 parents commit 4626dfa73b7847e9c42c1f799935f8242794d020
Showing 6 changed files with 288 additions and 0 deletions.
@@ -0,0 +1,61 @@
# npm – The Node Package Manager

npm is a little package manager for the Node javascript library.

## 5-Second(ish) Install

You should already have node installed and working. If you don't, go do that first.

Then, come back here, and run:


and it'll install itself and its requirements.

## Commands

You can get more details on any of these by doing `npm <command> --help`. Here are the basics.

All flags with two hyphens can be abbreviated to a single hyphen with the first letter, so you can also do `npm <command> -h` to get its info.

All commands return 0 if they succeed, and usually 1 if they don't. Normal output is on stdout, and oddness goes to stderr. Use the `--verbose` flag with any command to send extra debugging output to stderr.

### Managing Sources

npm learns all it knows about packages by looking at the JSON files specified in its catalog list. Manage this catalog list via the `npm source` commands.

### Update Package Metadata

Fetch the latest info from every source by doing `npm refresh`. Throw a `--force` on there if you want to clear the cache first.

It's a good idea to update every so often, maybe even put it on a weekly cron or something.

@TODO: Keep track of which packages were updated, and then
add them to an "outdated" list. Then, `npm update` could
be an alias to `npm refresh && npm install --force --outdated`

### Update Package Code

Version numbers aren't yet supported, so npm can't tell when a package has new code for you. If you know that it does, you can do `npm install --force <package>` to force-install the latest version.

### Find a Package

Find a package in the list by doing `npm search <string>`. If you only want to search through installed packages, then do `npm search --installed <string>`. If you only want to search through activated packages, then do `npm search --active <string>`.

### Activating/Deactivating Packages

Use `npm activate <package>`. Note that installing a package activates it by default, and uninstalling it deactivates it first.

### Starting/stopping Packages

Some packages are servers and the like that must be activated after being installed. To do this, do `npm start <package>`. To stop it, do `npm stop <package>`.

### Remove a Package

You can uninstall a package by doing `npm remove <package>`. This will first `stop` it if it's running, then remove its files from your system.

## Setting Defaults and Aliases via `$HOME/.npmrc`

Gee, it'd sure be nice to be able to have a `$HOME/.npmrc` file that could maybe pre-fix some of these options, dotcha think?

Write it, and send me a pull request, kthx.
@@ -0,0 +1,3 @@
#!/usr/bin/env node

77 npm.js
@@ -0,0 +1,77 @@
// the main guts

var npm = exports,
queue = require("./src/queue.js").queue,
http = require("/http.js");


npm.install = function npm_install () {
return dummyPromise()

npm.refresh = function npm_refresh () {
// return dummyPromise()
// get my list of sources.
var p = new node.Promise();
npm.getSources().addCallback(function (srcArr) {
queue(srcArr, function (src) {
return npm.refreshSource(src)
}).addCallback(function () {
}).addErrback(function () {
return p;

npm.getSources = function npm_getSources () {
var p = new node.Promise();, ".npm", "sources.json"))
.addErrback(function () {
p.emitError(new Error(
"Couldn't read " + node.path.join(ENV.HOME, ".npm", "sources.json") + "\n"
.addCallback(function (data) {
try {
data = JSON.parse(data);
if (data) p.emitSuccess(data);
} catch (ex) { p.emitError(ex); return; }
return p;

npm.refreshSource = function npm_refreshSource (src) {
debug("refresh the source: "+src);

var p = new node.Promise();

// var u = http.parseUri(src);
// var httpClient = http.createClient(uri.port || 80,;
// client.get(uri.path || "/", headers || {}), "utf-8", { "User-Agent" : "nodejs" })
.addCallback(function (data) {
debug("do something");
.addErrback(function (er) {
debug("error "+JSON.stringify(er)+ " " + JSON.stringify(res));

return p;

function dummyPromise (name) {
var promise = new node.Promise();
name = name ||;
setTimeout(function () {
node.stdio.writeError("TODO: implement "+ name + "\n");
return promise;

@@ -0,0 +1,5 @@
@@ -0,0 +1,96 @@

var npmDir = node.path.dirname(node.path.dirname(__filename)),
npm = require("../npm.js"),
queuePromise = new node.Promise();

exports.bootstrap = function bootstrap () {
node.stdio.writeError("npm: bootstrapping\n");
queuePromise.addCallback(function () {

function statTester (thing, test, success, failure) {
return function () {
node.fs.stat(thing).addCallback(function (stats) {
return (stats[test]()) ? success.apply(this, arguments)
: failure.apply(this, arguments);
// mkdir if not already existent.
// Doesn't handle mkdir -p, which would be nice, but is not necessary for this
function dirMaker (dir, mode, success, failure) {
return statTester(dir, "isDirectory", success, function () {
node.fs.mkdir(dir, mode).addErrback(failure).addCallback(success);

function fail (msg) { return function () {
node.stdio.writeError("npm bootstrap failed: "+msg);

function next () {
return script.shift()();

function done () {

var script = [
// make sure that the ~/.node_libraries and ~/.npm exist.
dirMaker(node.path.join(HOME, ".node_libraries"), 0755, next, fail(
"couldn't create " + node.path.join(HOME, ".node_libraries")
dirMaker(node.path.join(HOME, ".npm"), 0755, next, fail(
"couldn't create " + node.path.join(HOME, ".npm")

// If no in ~/.npm/sources.json, then copy over the local one
node.path.join(HOME, ".npm", "sources.json"), "isFile", next,
function () {
// try to copy the file over.
// seems like there outta be a node.fs.cp
node.path.join(npmDir, "sources.json")
"couldn't read " + node.path.join(npmDir, "sources.json")
)).addCallback(function (content) {
node.path.join(HOME, ".npm", "sources.json"),
node.O_WRONLY | node.O_TRUNC | node.O_CREAT,
"couldn't open "+node.path.join(HOME, ".npm", "sources.json")+" for writing"
)).addCallback(function (fd) {
node.fs.write(fd, content, 0).addErrback(fail(
"couldn't write to "+node.path.join(HOME, ".npm", "sources.json")

// call npm.refresh()
function () {
"Failed calling npm.refresh()"

// call npm.install("--force", "npm")
function () {
npm.install("--force", "npm").addErrback(fail(
"Failed installing npm with npm"


@@ -0,0 +1,46 @@

exports.queue = function queue (items, fn) {
return new Queue(items, fn).start();

// items are the things
// fn is what to do to each one.
// promise is the promise that is fulfilled when it works.
function Queue (items, fn) {
this.items = [];
for (var i = 0, l = items.length; i < l; i ++) if (i in items) {
this.fn = fn;
function Queue_next () {
if (this.items.length <= 0) return this.promise.emitSuccess();

var np = new node.Promise(),
self = this
np.addCallback(function () { });
setTimeout(function () {
try {
var fnP =, self.items.shift());
if (fnP instanceof node.Promise) fnP.addCallback(function () {
}).addErrback(function () {
else np.emitSuccess();
} catch (ex) {
return this.promise;

Queue.prototype = {
start : function Queue_start () {
if (this._started) return;
this._started = true;
this.promise = new node.Promise();
push : function (i) { this.items.push(i); }

5 comments on commit 4626dfa

Copy link

@dev-viinz dev-viinz commented on 4626dfa Aug 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, found the first commit :)

Copy link

@Loksly Loksly commented on 4626dfa Apr 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

found in npm birthday easter egg 📦

Copy link

@sech1p sech1p commented on 4626dfa Aug 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

first npm commit, wow

Copy link

@simondebbarma simondebbarma commented on 4626dfa Sep 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

me in the comment section


Copy link

@PCOffline PCOffline commented on 4626dfa Dec 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really great relic of the modern web

Please sign in to comment.