This blog post is a look how I automated most of my personal tasks when working with NodeJs and NPM. I strongly agree with Kent C Dodds and his list of reasons to automate even the smallest manual tasks. Investing a little time to write a tool that saves us a few seconds might seem like an unwise investment. Yet for me, each tool saves a lot more than a few seconds - it helps eliminate unnecessary distractions while I concentrate on the task at hand.
Here is a tiny screencast recorded using asciinema
showing several if the tools described below:
Here are the tools I wrote that I use over and over, hope they could be useful to someone else too. Give them a try, file an issue if you find a problem and spread the word by giving a tool a github star, or by tweeting about it.
Before proceeding, if you decide to install any of these tools, consider using all-nvm to install. This way the same tool will be installed in all Node versions on your machine, if you use NVM to manage multiple Node versions.
Tip: if you do not have Node installed on your machine, watch this video where I install Node on a Mac, and then install and open Cypress.
manpm - a Manual for NPM
- repo bahmutov/manpm
npm i -g manpm
manpm <package name> [optional search text]
I often have to lookup how to use a particular NodeJS module. Typically this means
npm home <module name> which opens a browser page, then looking or searching
through the page to locate a particular example. Opening a browser just to find
some text seems like an overkill, thus I wrote manpm. It looks up the README for a given
package and searches text inside to find the relevant section.
$ manpm chalk background ### Background colors + bgBlack + bgRed + bgGreen + bgYellow + bgBlue + bgMagenta + bgCyan + bgWhite
I can search a README file that is not associated with an NPM package, but from any
public github repo. For example, there are two popular repos that list ES6 features.
I declared a couple of aliases to
manpm <github repo> that now allow me to look up
ES6 examples quickly
$ echo 'alias es6-docs="manpm bevacqua/es6"' >> ~/.alias source ~/.alias es6-docs weaksets $ manpm bevacqua/es6 weaksets # WeakSets + WeakSet is sort of a cross-breed between Set and WeakMap + A WeakSet is a set that can't be iterated and doesn't have enumeration methods + WeakSet values must be reference types + WeakSet may be useful for a metadata table indicating whether a reference is actively in use or not + Read ES6 WeakSets in Depth (https://ponyfoo.com/articles/es6-weakmaps-sets-and-weaksets-in-depth#es6-weaksets) <sup>(back to table of contents) (#table-of-contents)</sup>
I became so lazy nowadays, I even search the local README file in the current folder! The search only prints the found section, allowing me to lookup the information without loosing focus.
manpm . [search text]
json-package - quickly prints package.json property
- repo bahmutov/json-package
npm i -g json-package
j <property name prefix>
If an NPM package follows all the best practices,
it will have a lot of properties in its
package.json file. For example, the
manpm package.json file is 99 lines long.
Printing this file in the terminal to find a particular value means scrolling and searching.
I often look up which dependencies a project uses, here is how quickly one can do this
json-package (it installs itself under
$ j d
The tool looks for the unique property that matches the prefix, and tries to be helpful if there is nothing matching or several results.
npm-quick-run - executes an NPM script without typing the full command
- repo bahmutov/npm-quick-run
npm i -g npm-quick-run
nr <npm script prefix>
I often test, lint and build source code; my favorite tool is not Grunt, Gulp, but simple
NPM script commands. It is tiresome to always type the full
npm run lint for example.
Instead I use my tool
The tool tries to be helpful, just like
json-package. If the supplied prefix matches
more than a single script key, it will list the choices.
$ nr s
semantic-release - never publish NPM module manually again
- repo semantic-release/semantic-release
npm i -g semantic-release-cli
This is not my tool, but I use it for most of my projects to automate the
npm publish command.
Instead of making a decision which semver number to increment and when to publish, my CI does that.
All I need is to follow a simple Git commit message format, and the rest is automated, including
the beautiful and useful release notes, see example.
I use pre-git as my Git hooks; it includes a commit
message wizard and validation to make sure everything is compatible with semantic release
conventions. When I commit using
npm run commit command (or better
nr c) I am asked a few
questions (this assumes I used the simple
commit log convention)
$ npm run commit
The full message will be something like
type(scope): short message
If the semantic release command that runs after the unit tests pass finds type
feat it will
publish a new version under version
x.y + 1, z where
x.y.z is the latest published version in NPM.
If the commit message has
fix(...): ... type, then it will be published under
x.y.z + 1. Finally,
BREAKING word in the full message body will increment the major
x + 1.y.z version.
By automating this pipeline I completely eliminated waiting for CI unit tests to finish, modifying and committing the changed version in the package.json, etc. It is a pure bliss - just work on the code, and let the machines worry about versioning.
If you use a private CI instead of TravisCI, I implemented a plugin for CircleCI, other CI services can be done similarly. Also, there is a plugin for reliable release if your project is tested via a matrix of NodeJS versions.
available-versions - what new versions are there?
- repo bahmutov/available-versions
npm i -g available-versions
vers <package name> [optional start version]
When you automate your publishing commands like I have done, all of the sudden your productivity
will sky rocket. Every push, every commit can become a new published version. This causes a tiny
problem: if I am working on the downstream project, it is often that there are newer versions.
How to quickly find what new versions can I use? Using
npm info <package name> is bad - it will
spit hundreds of output lines, and I will have to scroll back to find all available versions.
For example, because of its extensive list of contributors, lodash information is 748 lines long!
$ npm info lodash | wc -l
Finding all versions of lodash released after
3.0.0 version is a pain. This is where
$ vers lodash 3.0.0
Quick and simple. And if I want to upgrade to a newer version without breaking my code or testing it manually, I recommend using next-update of course.
center-code - showcase a piece of code in the terminal
- repo bahmutov/center-code
npm i -g center-code
I often do demos and presentations. Often I need to show a small piece of code in the terminal,
be it source code or
package.json or some markdown file. A large font is helpful, so is
clearing the terminal before showing the source. But I needed to make sure the code is using the
screen efficiently; instead of hugging the left margin of the terminal, I needed the code to be
in the center.
as-a - runs any command with additional environment variables
Keeping track of multiple environment variables (service urls, AWS secret keys, etc) and
passing them into local commands is a major pain. To make the pain go away I wrote
- repo bahmutov/as-a
npm i -g as-a
To use - create a single file in your user folder (private from everyone else)
Place all environment variables that you normally have to lookup there, separating them into sections. For example, if you use a central MongoDB setting like this
MONGODB=mongodb://sysop:[email protected]/records node server.js
Add the following section to
; local MongoDB server
Start the server using
as-a mongo node server.js
Simple and more secure.
A few more tools I recommend
- git-extras - all the Git aliases and tricks to make it simple
- gtni - git clone and npm install made into single command
- grunty - run any Grunt plugin without Grunt or Gruntfile
- pad-filenames - adds leading zeroes to filenames to fix sorting by filename difficulties