All the benefits of npm scripts without the cost of a bloated package.json and limits of json
npsis short for
Quick Video Intro 📺
Even though npm scripts have a ton of advantages (learn more), it can grow into an
unmaintainable mess in your
package.json file. Part of the problem is we're configuring scripts in
which has fundamental issues (like no comments).
nps is a package that solves this problem by allowing you to move your scripts to a
package-scripts.js file. Because
const npsUtils = // not required, but handy!moduleexports =scripts:default: 'node index.js'lint: 'eslint .'test:// learn more about Jest here:default: 'jest'watch:script: 'jest --watch'description: 'run in the amazingly intelligent Jest watch mode'build:// learn more about Webpack here:default: 'webpack'prod: 'webpack -p'// learn more about npsUtils here:validate: npsUtilsconcurrent
Or in case you prefer YAML, here's an example of how that would look in a
scripts:default: node index.jslint: eslint .test:# learn more about Jest here:default: jestwatch:script: jest --watchdescription: run in the amazingly intelligent Jest watch modebuild:default: webpackprod: webpack -pvalidate: concurrent "nps lint" "nps test" "nps build"
nps, it's recommended that you either install it globally (
npm i -g nps) or add
./node_modules/bin to your
$PATH (be careful that you know what you're doing when doing this, find out how here).
Then you can run:
Which will output:
Usage: nps [options] <script>...Commands:init automatically migrate from npm scripts to npscompletion generate bash completion scriptOptions:--config, -c Config file to use (defaults to nearest package-scripts.ymlor package-scripts.js)[default: "<path-to-your-project>/package-scripts.js"]--silent, -s Silent nps output [boolean] [default: false]--log-level, -l The log level to use[choices: "error", "warn", "info", "debug"] [default: "info"]--require, -r Module to preload-h, --help Show help [boolean]-v, --version Show version number [boolean]--help-style, -y Style of help to use[choices: "all", "scripts", "basic"] [default: "all"]Examples:nps.js test build Runs the `test` script then the`build` scriptnps.js "test --cover" "build --prod" Runs the `test` script and forwardsthe "--cover" flag then the `build`script and forwards the "--prod"flagAvailable scripts (camel or kebab case accepted)lint - eslint .test - jesttest.watch - run in the amazingly intelligent Jest watch mode - jest --watchbuild - webpackbuild.prod - webpack -pvalidate - concurrent "nps lint" "nps test" "nps build"
You can also use the help command with a script name
nps help test.watch
Which will output the details of the script
test.watch - run in the amazingly intelligent Jest watch mode - jest --watch
Now, to run a script, you can run:
nps lintnps test.watch# etc.
But the fun doesn't end there! You can use a prefix:
nps b # will run the build scriptnps help b # will display help for the build script
And these prefixes can go as deep as you like!
nps b.p # will run the production build script
Cool stuff right? And there's more on the roadmap.
Also check out the examples. You'll find some good stuff in there (including how to deal with windows and other cross-platform issues).
Note: If you don't like installing things globally and don't want to muck with your
$PATH (or don't want to
require that your co-workers or project contributors to do so), then you can add a single script to your
We recommend that you use the
start script because it requires less typing:
You don't have to use the
start script if you don't want. Note that if you're writing a node application, you're
start for starting your server. In that case, you can create a
default script which will be run
nps is run without arguments (so effectively it'll work just the same). But if you'd prefer, you can use whatever
you wish. For example you could easily create a
nps script and do:
npm run nps b.
npm install --save-dev nps
You can install this module globally also (this is recommended):
npm install --global nps
From here you can use
nps on the command line via one of the installed aliases:
If you do this, you may also be interested in installing the shell autocompletion script. See more about this below.
If you're already using npm scripts, you can get up and going really quickly with the
./node_modules/.bin/nps init --type yml
This will use your
scripts to generate a
package-scripts.js (respectively a
file and update your
scripts to utilize the
If you have a
help script, then your
help script will be run. Otherwise, this will output the help.
Note: you can do this with
nps --help, but if you're using the
startscript in your
package.jsonthis allows you to run
npm start helprather than
npm start -- --help
As indicated above, this will migrate your npm scripts to package-scripts.
nps completion >> <your-bash-profile-file>
<your-bash-profile-file> will be
Note: you should probably only do this if you have the package installed globally. In that case you should probably also
normally use the
nps alias rather than
nps because it's easier to type.
Will print out the help you see above (the available scripts are colored 🌈 and come from the config specified/default config).
nps will log out to the console before running the command. You can add
-s to your command to silence
By default, the script's command text will log out to the console before running the command. You can add
--no-scripts to prevent this.
Use a different config
nps -c ./other/package-scripts.js lint
nps will look for a
package-scripts.js file and load that to get the scripts. Generally you'll want to
have this at the root of your project (next to the
package.json). But by specifying
use that file instead.
Specify the log level to use
You can specify a module which will be loaded before the config file is loaded. This allows you to preload for example babel-register so you can use all babel presets you like.
To run a script, you simply provide the name of the script like so:
And you can run multiple scripts in series by simply adding more space-separated arguments.
nps cover check-coverage
And you can pass arguments to scripts by putting the scripts in quotes:
nps "test --cover" check-coverage
nps will dump a very long help documentation to the screen based on your package-scripts.js file. You can modify this output with one of three help-style options:
all gives you the normal default output:
nps help "--help-style all"
scripts will give you only the help information built from your package-scripts.js file
nps help "--help-style scripts"
basic will give you only the name and description of the scripts from your package-scripts.js file
nps help "--help-style basic"
That's all for the CLI.
nps expects to your
package-scripts.js file to
module.exports an object with the following properties:
This can be an object or a function that returns an object. See the annotated example below for what this object can look like (and different ways to run them):
moduleexports =scripts:default: 'echo "This runs on `nps`"' // nps// you can assign a script property to a stringsimple: 'echo "this is easy"' // nps simple// you can specify whether some scripts should be excluded from the help listhidden:script: 'debugging script'hiddenFromHelp: truetest:default:script: 'jest' // nps testdescription: 'Run tests with jest'// your scripts will be run with node_modules/.bin in the PATH, so you can use locally installed packages.// this is done in a cross-platform way, so your scripts will work on Mac and Windows :)// NOTE: if you need to set environment variables, I recommend you check out the cross-env package, which works// great with npsotherStuff:// this one can be executed two different ways:// 1. nps test.otherStuff// 2. nps test.other-stuffscript: 'echo "testing other things"'description: 'this is a handy description'// this one can be executed a few different ways:// 1. nps k// 2. nps kebab-case// 3. nps kebabCase'kebab-case': 'echo "kebab-case"'series: 'nps simple,test,kebabCase' // runs these other scripts in series
nps k # runs nps kebab-case
This object is used to configure
nps with the following options:
Setting this to
true will prevent
nps from outputting anything for your script (normally you'll get simple output
indicating the command that's being executed). This effectively sets the
This sets the logLevel of
LOG_LEVEL environment variable you can control the log level for
Log levels available:
error- errors only
warn- errors and warnings only
info- info, errors, and warnings (default)
Congratulations your repo is nps-friendly. Time to flaunt it! Add the nps-friendly badge to your README using the following markdown:
Your badge will look like this:
It may also make sense to change your README.md or CONTRIBUTING.md to include or link to the nps project so that your new contributors may learn more about installing and using nps.
How do I do ___ ?
Have you looked at the examples in other/EXAMPLES.md?
Just to be clear: You do not have to use the
start script. You can use whatever you like. But I recommend using
start. npm scripts are generally run with
npm run <script-name>. There are some exceptions to
this. For example:
npm run test===
npm run start===
So, while you could use a script called
script and run
npm run script build, I just think it reads more clearly to
just use the
start script and run
npm start build. It's also nice that it's fewer things to type. You could also use
test script and then type even less:
npm t build, but thats just... odd.
Note, often servers are configured to run
npm start by default to start the server. To allow for this case, you can
default script at the root of your scripts which will be run when
npm start is run without any arguments.
Effectively this will allow you to have a script run when
npm start is executed.
nps-utils- a collection of utilities to make cross-platform scripts and many other patterns (like running concurrent/parallel scripts)
- scripty has a solution for this problem as well. The reason I didn't go with that though is you still need a line for every script (one of the pains I'm trying to solve) and a each script requires its own file (one of the benefits of npm scripts I wanted to keep).
- nabs is a compiler that turns a nicely structured YAML file into script entries in your package.json
What happened to p-s?
This project is p-s! It was just renamed during a major version bump. There were a few breaking changes for this to happen and those are documented on the releases page.
Thanks goes to these people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!