This article is about saving time and space when developing using node. It is about a little known program written to run solely in bash. A program easily ported to any developer station. A program written only in bash and hence, only dependent on bash to run. A script intended to take some of the fat out of npm. The name of the script is lnpm and you can find it at https://github.com/dcorns/lnpm.sh .

If you are doing a lot of node projects, you may have noticed as I did that every project ends up with its own node_modules directory full of the modules it requires. Many of the same modules end up all over your hard drive as they are duplicated in every project directory. With lnpm, you no longer need to put up with the wasting of space.

Additionally, you will notice that the way that npm requires you to install these modules is by connecting to the internet to download the same packages over and over again. Not only is this a time waster, but if your Internet connection goes down you can forget about adding any modules to you project unless you hunt them down from another project and copy them over, and manually edit your package.json file. As you may have guessed lnpm has a solution for this also.

And what if you need to change the version of any of the modules you are using. lnpm makes this easier also.

lnpm is a public bash script that you can clone in from https://github.com/dcorns/lnpm.sh that replaces the more commonly used npm commands enabling you to store and manage your node modules in a local folder or network drive. It is simple to use, makes efficient use of available storage, and performs lightning fast installs of node modules. The remainder of this article describes its features in more detail.

Before going on let me ease your concerns about this script forcing you into some new realm where the old npm will never work with your projects again. lnpm works with the existing npm implementation in such a way that should you want to return to storing duplicate files all over your system and waiting for a slow Internet connection to continue writing your code, it can be done simply by removing the node_modules directory in your project and running npm install.

In order to start using lnpm, you need to do five things;

Clone or copy the script from https://github.com/dcorns/lnpm.sh Make the script executable on your system. Store the script in a directory that is currently a part of your path or add its location to your exiting path. Create a directory for the purpose of storing your modules.

Add the following statement to your ~/.bashrc file: export LNPMDIR=<put the full path of the directory you created in step 4 here>.

For more details on how to accomplish these steps see the lnpm readme https://github.com/dcorns/lnpm.sh/blob/master/README.md

There are a number of ways modules are added to the lnpm local directory.

You can copy existing modules to your lnpm directory and run "lnpm configure" Modules are installed as a result of running any lnpm install operation if they do not already exist. You can npm install a module while in the lnpm directory and then run "lnpm configure"

There are three lnpm commands that operate on the lnpm directory regardless of the current working directory.

configure

update

revert

I covered configure already. Here is the run down on the other two:

update; as the name implies, is for updating your lnpm directory with the latest npm module available. An important distinction to make here is that lnpm never replaces modules with an update. If a later version of a given module exists, it will be added to the directory along with any preexisting versions. You can run update with no argument or with a module name as an argument. Be aware that if you run lnpm update without a module name, all the modules in the directory will be checked for later versions which will be added if they do not exist. If you have a large number of modules installed, updating them all may take a while.

revert; To allow for local version control and availability locally, each directory used by lnpm uses the following naming convention: <modulename>--<version>. The revert command changes these directories back to the npm module name. The exception to this is when there is more than one version of a module in the lnpm directory. In that case, the directory name remains the same for each affected version so you can choose which version to keep and which versions to move or delete.

That is it for the commands relating only to the lnpm directory. Another command, though not part of lnpm, worth mentioning is the bash command ls. When applied to the lnpm directory,, it will, of course list all the modules you have installed that are available through lnpm.

All the commands in the rest of this article are scoped to the directory in which they are executed and as such should be run while in the top directory of the project. This is the same directory in which you would be running npm commands in order to install modules. There are two commands to describe before getting into the meat of things; that is lnpm install. They are lnpm convert and lnpm copy.

lnpm convert takes an existing project directory previously populated by npm and converts it for use with lnpm. When lnpm convert executes, the contents of the project's node_modules directory is replaced with symbolic links to the lnpm directories containing the modules that are specified in the project's package.json file. If a module in the package.json file is not contained in the lnpm directory, it is downloaded, configured for use.

lnpm uses symbolic links to the centralized lnpm directory in order to facilitate reclaiming the space that is wasted by the typical node project install. In most cases it works fine, but in some cases a module will not work by reference through a symbolic link. That is why lnpm includes the copy command. lnpm copy <module> will copy the actual module directory from the lnpm directory to the node_modules sub directory of the project directory, replacing the symbolic link.

It is worth stating at this point that none of the commands described so far manipulate the existing package.json file. The most useful command that follows, will do so in some cases as that is often why it is so useful.

lnpm install: lnpm install works in much the same way as npm install so, other than using centralized storage, the commands basically do the same things. However the differences should be pointed out as these are the reasons lnpm exists. One difference is by nature of the fact that lnpm stores all the modules for installations locally. lnpm install will always attempt to download a requested module from npm if it does not already exist in the lnpm directory.

lnpm install without arguments is to be used when starting a new project with lnpm or after an existing project has been converted to lnpm using lnpm convert. Do not use lnpm install in an npm project directory that has not been converted using lnpm convert unless you first remove the existing node_modules directory. This is because the node_modules directory will already contain directories for modules that will conflict with the symbolic links lnpm install creates.

If lnpm install is run without any module arguments, it will attempt to install from a package.json. If the package.json does not exist, it will generate an error. If the package.json does exist, lnpm will verify that the modules exist in the lnpm directory and if not it will download them into the lnpm directory. Then it will create the node_modules directory if it does not exist and store symbolic links to the respective directories in the node_modules directory.

lnpm install <module's>: In this case if the package.json does not exist, npm init will be called to create it interactively. Then the modules will be added to the dependencies section in the package.json, and if needed installed into the lnpm directory. Then the symbolic links will be added to the node_modules directory. Since lnpm supports multiple versions of modules, if multiple versions of a module are installed in the lnpm directory you will be offered a selection list.

Like npm –save will add the module,s to the package.json dependencies section and –save-dev will add the module,s to the package.json devdependencies section. Unlike npm the –save and –save-dev arguments must be placed after all the module arguments to be evaluated properly when using lnpm install.

For example: lnpm install grunt mocha chai –save-dev

When lnpm reads a package.json, it expects it to comply with the semversion specification as laid out in https://www.npmjs.org/doc/misc/semver.html , but mullti version ranges like version - version are not supported by lnpm. If you want to load the latest version of a module that is available from the npm registry, make sure and run lnpm update before running lnpm install unless you are using a package.json to install. Furthermore when a module is added to a package.json with npm, the version is prefixed with a carrot '^' to indicate any compatible version. lnpm install does not prefix the version when adding it to the package.json. lnpm can interpret these prefixes, but since it allows you to choose any available version during the install, it always writes the package.json with the more predictable exact version for each project.

lnpm is not a complete replacement for npm, but it will make the most common development tasks where node is used faster and less storage intensive. Give it a try, if you find a problem, let the author know, or better yet join the author in this ongoing project by submitting a pull request.