javascriptnode.jsnpm

Sending command line arguments to npm script


The scripts portion of my package.json currently looks like this:

"scripts": {
    "start": "node ./script.js server"
}

...which means I can run npm start to start the server. So far so good.

However, I would like to be able to run something like npm start 8080 and have the argument(s) passed to script.js (e.g. npm start 8080 => node ./script.js server 8080). Is this possible?


Solution

  • npm 2 and newer

    It's possible to pass args to npm run since npm 2 (2014). The syntax is as follows:

    npm run <command> [-- <args>]

    Note the -- separator, used to separate the params passed to npm command itself, and the params passed to your script. (This is a common convention used by various command line tools).

    With the example package.json:

    "scripts": {
        "grunt": "grunt",
        "server": "node server.js"
    }
    

    here's how to pass the params to those scripts:

    npm run grunt -- task:target  // invokes `grunt task:target`
    npm run server -- --port=1337 // invokes `node server.js --port=1337`
    

    Note: If your param does not start with - or --, then having an explicit -- separator is not needed; but it's better to do it anyway for clarity.

    npm run grunt task:target     // invokes `grunt task:target`
    

    Note below the difference in behavior (test.js has console.log(process.argv)): the params which start with - or -- are passed to npm and not to the script, and are silently swallowed there.

    $ npm run test foobar
    ['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js', 'foobar']
    
    $ npm run test -foobar
    ['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js']
    
    $ npm run test --foobar
    ['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js']
    
    $ npm run test -- foobar
    ['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js', 'foobar']
    
    $ npm run test -- -foobar
    ['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js', '-foobar']
    
    $ npm run test -- --foobar
    ['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js', '--foobar']
    

    The difference is clearer when you use a param actually used by npm:

    $ npm test --help      // this is disguised `npm --help test`
    npm test [-- <args>]
    
    aliases: tst, t
    

    To get the parameter value, see this question. For reading named parameters, it's probably best to use a parsing library like yargs or minimist; nodejs exposes process.argv globally, containing command line parameter values, but this is a low-level API (whitespace-separated array of strings, as provided by the operating system to the node executable).