How to Pass Command Line Arguments to NPM Scripts: A Complete Guide

How to Pass Command Line Arguments to NPM Scripts: A Complete Guide
Photo by Paul Esch-Laurent / Unsplash

Alright, so you wanna pass arguments to your NPM scripts, huh? Let's break down how to do it.

Most Node.js projects will expect you to pass arguments via the command line for your npm scripts. Whether you are working with build processes, environment variables, or any other configuration, knowing how to give arguments properly to your npm scripts is pivotal to smooth development processes.

Understanding the Problem

This problem of passing different arguments is very common among developers. Let’s say you have a script that needs to be run with a certain configuration or a specific set of environment variables. Instead of hardcoding them into your application, you may want to include general options in your package.json.

The Solution: Using Double Dashes (--)

The best way to pass specific arguments to npm scripts is using double dash (--) separator. which informs npm to take everything past – and add it directly to the script or command being passed.

Basic Syntax

npm run <script-name> – <arguments>

Example: Basic Argument Passing

Let's say you have a script in your package.json:

{
  "scripts": {
    "start": "node server.js",
    "test": "jest",
    "build": "webpack"
  }
}

To pass arguments to the start script:

npm run start – --port=3000 --env=development

This is equivalent to running:

node server.js --port=3000 --env=development

Common Use Cases and Examples

1. Passing Environment Variables

{
  "scripts": {
    "start": "node server.js",
    "start:dev": "NODE_ENV=development npm run start"
  }
}

Run with custom port:

npm run start – --port=8080

2. Testing with Specific Parameters

{
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch"
  }
}

Run tests with coverage:

npm run test – --coverage --verbose

3. Build Scripts with Configuration

{
  "scripts": {
    "build": "webpack --mode=production",
    "build:dev": "webpack --mode=development"
  }
}

Build with custom output directory:

npm run build – --output-path=./dist/custom

Advanced Techniques

Using npm_config Variables

NPM automatically creates environment variables for command line arguments prefixed with npm_config_:

npm run start --port=3000

In your script, you can access this as:

// In your Node.js script
const port = process.env.npm_config_port || 3000;
console.log(`Server running on port ${port}`);

Cross-Platform Environment Variables

For cross-platform compatibility, use the cross-env package:

{
  "scripts": {
    "start": "cross-env NODE_ENV=production node server.js"
  }
}

Install cross-env:

npm install --save-dev cross-env

Using process.argv in Node.js Scripts

In your Node.js scripts, you can access command line arguments through process.argv:

// server.js
const args = process.argv.slice(2);
const portArg = args.find(arg => arg.startsWith('--port='));
const port = portArg ? portArg.split('=')[1] : 3000;
console.log(`Starting server on port ${port}`);

Best Practices

1. Document Your Script Arguments

Always document the available arguments in your README or package.json comments:

{
  "scripts": {
    "start": "node server.js",
    "// start": "Available arguments: --port=<number>, --env=<environment>"
  }
}

2. Provide Default Values

Ensure your scripts work with sensible defaults:

const port = process.env.PORT || process.env.npm_config_port || 3000;
const env = process.env.NODE_ENV || process.env.npm_config_env || 'development';

3. Use Argument Parsing Libraries

For complex argument handling, consider using libraries like yargs or commander:

const yargs = require('yargs');
const argv = yargs
  .option('port', {
    alias: 'p',
    description: 'Port to run the server on',
    type: 'number',
    default: 3000
  })
  .option('env', {
    alias: 'e',
    description: 'Environment to run in',
    type: 'string',
    default: 'development'
  })
  .help()
  .argv;
console.log(`Server running on port ${argv.port} in ${argv.env} mode`);

Common Pitfalls and Solutions

1. Forgetting the Double Dash

❌ Wrong:

npm run start --port=3000

✅ Correct:

npm run start – --port=3000

2. Order of Arguments Matters

The -- must come before your custom arguments:

❌ Wrong:

npm run start --port=3000 --

✅ Correct:

npm run start – --port=3000

3. Quoting Arguments with Spaces

When passing arguments with spaces, use quotes:

npm run test – --testNamePattern="user login"

Alternative Approaches

Using Environment Variables

Instead of command line arguments, you can use environment variables:

PORT=3000 NODE_ENV=development npm run start

Creating Multiple Scripts

For commonly used configurations, create separate scripts:

{
  "scripts": {
    "start": "node server.js",
    "start:dev": "NODE_ENV=development PORT=3000 npm run start",
    "start:prod": "NODE_ENV=production PORT=8080 npm run start"
  }
}

Conclusion

For more complex development tasks, being able to modify npm scripts via the command line is an extremely useful addition to your workflow. With the right understanding of how npm processes arguments along with proper usage of the double dash (--) separator, you will be able to create many versatile scripts fitting for different environments.

Do not forget to document your arguments with clear reasoning for their values, or make use of argument handling libraries for more intricate use cases. With all of these suggestions combined, you can create maintainable and flexible npm scripts tailored appropriately for the requirements of your projects.

Quick Reference

  • Use npm run script -- --arg=value to pass arguments
  • Access arguments via process.argv in Node.js
  • Use npm_config_ environment variables for automatic access
  • Consider cross-env for cross-platform compatibility
  • Document your script arguments for team collaboration

Mastering npm script arguments will significantly improve your development efficiency, whether you're building applications, running tests, or automating tasks.