A compilation of best practices on how to build successful, resonant, and user-friendly Node.js command-line interface (CLI) applications.

Why this guide?

A bad CLI can easily discourage users from interacting with it. Building a successful CLI requires attention to detail and compassion for users in order to create a good user experience. It’s easy to go wrong.

In this guide, I’ve compiled a list of best practices in key areas designed to optimize the ideal user experience when interacting with CLI applications.

The characteristic.

  • 21 Best practices for building successful Node.js CLI applications
  • ✅ Read in different languages. 🇨🇳, 🇪🇸, or help with translation into other languages. [🇩 🇪,…
  • 🙏 Welcome

Why me?

Hi, I’m Liran Tal, and I’m obsessed with building command-line applications.

Some of my recent work, building the Node.js CLI, includes the following open source projects.

Team ✨

Thanks to these wonderful people (emoji keys).



Vanilla

🌍



turkel

🖋



Jason Karns

🖋



Dave Sager

🚧



José J. Pérez Rivas

🌍



Suresh Raj

🖋


directory

  • 1 Command Line experience
    • 1.1 Respect POSIX ARGS
    • 1.2 Building the CLI of Empathy
    • 1.3 Stateful data
    • 1.4 Provide rich and colorful experience
    • 1.5 Rich interactivity
    • 1.6 Ubiquitous hyperlinks
    • 1.7 the zero configuration
    • 1.8 Respect POSIX signals
  • 2 distribution
    • 2.1 Tends to rely on small footprints
    • 2.2 Use thumbnails, Luke
    • 2.3 Clearing Configuration Files
  • 3 Interoperability
    • 3.1 Accept input as STDIN
    • 3.2 Enabling structured Output
    • 3.3 Cross-platform etiquette
    • 3.4 Setting priorities
  • 4 Accessibility
    • 4.1 Containerizing the CLI
    • 4.2 Graceful Degradation
    • 4.3Node.js Versions Compatible
    • 4.4Shebang automatically detects the runtime of Node.js
  • 5 test
    • 5.1 Distrust of regionalism
  • 6 error
    • 6.1 Traceable errors
    • 6.2 Operable errors
    • 6.3 Debugging mode
    • 6.4 Use exit codes correctly
    • 6.5 Effortless error reporting
  • 7 development
    • 7.1 Using the bin Object
    • 7.2 Using a Relative Path
    • 7.3 Using File Fields

1 Cli experience

This section covers best practices related to creating beautiful and high-value user experience Node.js command-line applications.

In this section.

  • 1.1 Respect POSIX ARGS

  • 1.2 Building the CLI of Empathy

  • 1.3 Stateful data

  • 1.4 Provide rich and colorful experience

  • 1.5 Rich interaction

  • 1.6 Ubiquitous hyperlinks

  • 1.7 the zero configuration

  • 1.8 Respect POSIX signals

1.1 Respect POSIX Parameters

✅ ** do: ** Use POSIX-compliant command-line argument syntax, which is widely accepted as standard for command-line tools.

** Otherwise: ** Users can get frustrated when the syntax of CLI arguments, options, or command arguments deviates from the de facto Unix standard to which they are accustomed.

ℹ ️ details

Unix-like operating systems popularized the use of command lines and tools, such as AWk,sed. These tools effectively regulate the behavior of command-line options (aka flags), option-arguments, and other operands.

Some examples of expected behavior.

  • Options – Parameters or options can be in help or examples with square brackets ([]) to indicate that they are optional, or with Angle brackets (<>) means they are required.
  • Allows short-form single-letter arguments to be aliases for long-form arguments (see reference to the GNU coding standard).
  • Use the short singular form-The option can contain an alphanumeric character.
  • Specifies that multiple options with no value can be grouped, for examplemyCli -abcIs equivalent tomyCli -a -b -c

Command line users will expect your command line application to have similar conventions to other Unix applications.

📦 Recommended software package

Refer to the open source Node.js package.

  • yargs

1.2 Building the CLI of Empathy

✅ ** Do: ** Establish a workflow to help users successfully interact with the CLI that would otherwise lead to errors and frustration.

** Otherwise: ** If no actionable help is provided to support the user, the user will be frustrated due to the lack of CLI operation ability.

ℹ ️ details

The command line interface of your program is no different from the web user interface, and as the author of the program, you will do your best to ensure that it is used successfully.

Optimize successful interactions by building a sympathetic CLI that supports users. As an example, let’s look at the curl program, which expects a URL as its primary data input, and the user fails to provide it. Such a failure would result in the user reading (hopefully) descriptive error messages or looking at curl –help output. However, an empathetic CLI will come up with an interactive prompt to capture the user’s input, leading to a successful interaction.

1.3 Stateful data

✅ ** Do: ** Provide a stateful experience between multiple calls to your CLI application, and remember values and data to provide seamless interaction.

** Otherwise: ** Requiring your users to provide the same information repeatedly when calling the CLI multiple times will annoy your users.

ℹ ️ details

You may find yourself needing to provide storage persistence for your CLI application, such as remembering a user name, email, API token, or other preferences over multiple CLI calls. Use a configuration helper to enable your application to persist such user Settings. Be sure to follow the XDG base directory specification (or choose a configuration helper that respects that specification) when reading/writing files. These allow users to maintain control over where files are written and managed.

Reference project.

  • configstore
  • conf

1.4 Provide colorful experience

✅ ** Do: ** Use colors in your CLI application to highlight the output portion of your application, and provide an elegant degradation, or color detection, to allow automatic opt-out so that the output is not garbled. Ensure that you can manually select in and out through CLI options, environment variables, and/or configuration files.

** Otherwise: ** Information can easily be lost in pale program output, especially if the output is a lot of text.

ℹ ️ details

Today, most terminals used to interact with command line programs support colored text, such as these enabled by specially made ANSI-encoded characters.

Color displays in the output of your command line application may further facilitate a richer experience and increased interaction. In other words, unsupported terminals may have a messy form of information on the screen, resulting in poor output. In addition, CLI may be used in continuous integration build efforts, which may not support color output. Even outside of the build server, the CLI may be used through the IDE’s console, which may not be able to handle certain characters. Manual opt-out must be provided.

Reference project.

  • chalk
  • color
  • kleur

📦 Recommended Software Packages

Refer to the open source Node.js package.

  • The cretaceous
  • color
  • kleur

1.5 Rich interaction modes

✅ ** Do: ** Take advantage of rich command line interaction that goes beyond basic text input prompts to provide a smoother experience for CLI users.

** Otherwise: ** Text prompts as input can cause problems for users when the data to reason about is in the form of closed options (i.e., drop-down menus).

ℹ ️ details

Rich interactivity can be introduced in the form of prompt input, which is more complex than free text, drop-down selection lists, radio button toggles, ratings, auto-complete or hidden password entry.

Another rich form of interactivity comes in the form of animation loaders and progress bars that provide a better user experience when working asynchronously.

Many CLI’s provide default command-line arguments without requiring any further interactive experience. Don’t force your users to provide parameters that the application can solve on its own.

📦 Recommended software package

Refer to the open source Node.js package.

  • enquirer
  • ora
  • The ink
  • The clues

1.6 Hyperlinks are everywhere

✅ ** does: ** Use properly formatted hyperlinks to urls (e.g. https://www.github.com) and source code (e.g. SRC/util.js :2:75) in text output – modern terminals can convert both into clickable links.

❌ ** Otherwise: ** Avoid broken and non-interactive links like git. IO/ABC that require users to manually copy and paste.

ℹ ️ details

If you are sharing a link to a URL, or to a file and a specific row number and column in the file, you can provide a properly formatted link for both examples that, once clicked, will open a browser, or an IDE that defines the location.

Reference project.

  • Open the

1.7 the zero configuration

✅ ** Do: ** Optimize the plug and play experience by automatically detecting required configuration and command-line parameter values.

** Otherwise: ** Do not force the user to interact if command line arguments can be automatically detected in a reliable manner and the invoked operation does not explicitly require the user to interact (such as confirm deletion).

ℹ ️ details

Strive to provide an “out of the box” experience when running CLI applications. For example, POSIX defines a standard for configuring environment variables for different purposes, such as TMPDIR,NO_COLOR,DEBUG,HTTP_PROXY, and so on. Detect these automatically and prompt confirmation if necessary.

Consider projects that revolve around zero configuration.

  • Jest JavaScript testing framework
  • Parcel, a web application bundler

1.8 Respect POSIX signals

✅ ** Do: ** Make sure your program respects POSIX signals in order to interact properly with users or other programs.

** Otherwise: ** Your program will not interact well with other programs and will introduce unexpected behavior.

ℹ ️ details

For CLI applications in particular, interacting with user input is common, and improperly managing keyboard events can cause your application to fail to respond to SIGINT interrupts, which users typically use when they hit CTRL+C.

The problem of disrespecting process signals worsens when programs are coordinated by non-human interactions. For example, a CLI that runs in a Docker container but does not respond to software interruption signals sent to it.

2 distribution

This section covers best practices for the best way to distribute and package Node.js command-line applications for consumers.

In this section.

  • 2.1 tends to choose a small dependency footprint
  • 2.2 Using ShrinkWrap, Luke
  • 2.3 Clearing Configuration Files

2.1 Tends to have a small dependency footprint

** Minimize the use of production dependencies, use smaller alternative dependencies, and review the footprint of dependencies to ensure a small bundle of Node.js CLI. To balance this, be careful not to over-optimize the use of dependencies by reinventing the wheel.

** Otherwise: ** The size and usage of dependencies in your application will affect the installation time of your Node.js CLI and may provide a poor user experience.

ℹ️ Details

Quick NPM install for node.js CLI with NPX calls will provide a better user experience. This is possible when the overall dependency and cross-dependency footprint is kept to a reasonable size.

One-off global NPM installation A slowly-installed NPM package will provide a one-off bad experience, but users using NPX to invoke executable packages will degrade performance, which is all the more noticeable since NPX always gets and installs packages from the registry.

Reference project.

  • Bundlephobia is a tool to help you find out the cost of an NPM package.

2.2 Using ShrinkWrap, Luke

✅ ** Do: ** Use NPM’s Npm-shrinkwrap. Json as the lock file to ensure that the nPm-dependent versions (direct and landscape) are propagated to your end users when they install your NPM package.

❌ ** Otherwise: ** Not fixing the dependent version of your application will mean that a package manager (such as NPM) will address these issues during installation, and horizontal dependencies installed through the version range may introduce disruptive changes that you have no control over, which may cause your Node.js CLI application to not build or run.

ℹ ️ details

Use the force shrink pack, Luke!

Typically, an NPM package defines only its direct dependencies and their version range at installation time, and the NPM package manager resolves all versions of horizontal dependencies at installation time. Over time, the parsed versions of dependencies can vary as new direct and cross dependencies are released.

Although Semantic Versioning is widely accepted by maintainers, it is well known that NPM introduces many dependencies for a common package being installed, increasing the risk that a package introduces changes that could break your application.

The flip side of using NPM-Shrinkwrap. Json is the security impact you’re imposing on consumers. Installed dependencies are pinned to a particular version, so they are not installed even if newer versions of these dependencies are released. This puts the onus on you, the maintainer, to keep your dependencies up to date with security fixes and to release regular security updates to the CLI application. Consider using Snyk dependency upgrades to automatically fix security issues throughout the dependency tree. Full disclosure: I’m a developer advocate for Snyk.

👍 prompt

Use the NPM shrinkwrap command to generate a shrinkwrap lockfile in the same format as the package-lock.json file.

Resources.

  • Do you really know how lockfile for YARN and NPM packages works?
  • Yarn document. Should lock files be committed to the repository?

2.3 Clearing Configuration Files

✅ ** Do: ** Clear configuration files when CLI applications are uninstalled. Alternatively, the CLI application can prompt your users to keep the configuration files so that they can skip the reinitialization phase for a better user experience the next time they install.

** Otherwise: ** The user’s file system may contain remnants in the form of ownless configuration files and identifiable data introduced during installation by CLI tools.

ℹ ️ details

As mentioned in the stateful Data section, if your CLI application uses persistent storage, such as saving configuration files, then the CLI application should also be responsible for deleting its configuration files when it is uninstalled.

You can do this using NPMspre or POST uninstall scripts. You can find a working example in this repository.

3 Interoperability

This section covers best practices for seamlessly integrating your Node.js CLI with other command-line tools, and follows the natural conventions of CLI operation.

This section answers the following questions.

  • Can I export this CLI output for easy parsing?
  • Can I pipe the output of this CLI to the input of another command line tool?
  • Can I funnel the results of another tool to this CLI?

In this section.

  • 3.1 Accept input as STDIN
  • 3.2 Enabling structured Output
  • 3.3 Cross-platform etiquette
  • 3.4 Setting priorities

3.1 Accept input as STDIN

✅ ** Do: ** For command line applications that need to process data, make it easy for users to pipe data to standard input (STDIN).

** Otherwise: ** Other command line programs will not be able to provide their results directly as input to your CLI, which will prevent common UNIX one-liners like:.

$ curl -s 
Copy the code

ℹ ️ details

If a command line application does something to the data, such as performing some kind of task on a JSON file that is typically specified with the –file

command line argument.

An example of how the for Readline module based on the official Node.js API Docs gets input from the command pipeline is shown below.

const
Copy the code

The input is then piped into the above Node.js application.

echo
Copy the code

3.2 Enabling structured Output

✅ ** does: ** Enables a flag to allow structured output of the application’s results, if any, to make parsing and easy manipulation of the data.

** Otherwise: **CLI users may need to apply sophisticated Regex parsing and matching techniques to extract the output data provided by your CLI.

ℹ ️ details

It is often useful for users of command-line applications to parse the data and perform other tasks on it, such as using it to provide network dashboards, or E-mail notifications.

The ability to easily extract data of interest from the command line output provides a more user-friendly experience for your CLI users.

3.3 Cross-platform Etiquette

✅ ** Do: ** If the CLI is expected to run cross-platform, proper attention must be paid to the semantics of the command shell and components such as the file system, while developers take advantage of the associated programming structures.

Otherwise, the CLI can fail on other operating systems due to factors such as incorrect path separators, even if there are no functional differences in the code.

ℹ ️ details

Even if functionality isn’t stripped from the program’s point of view, and _ should _ perform well on different operating systems, some missing nuances can make the program unusable. Let’s explore a few cases where cross-platform ethics must be followed.

Mistakenly spawning a command

You may need to spawn a process that runs node.js programs. For example, you have the following script.

program.js

#! /usr/bin/env nodeCopy the code

This will do.

const cliExecPath = 'program.js'
const process = childProcess.spawn(cliExecPath, [])
Copy the code

This is better.

const cliExecPath = 'program.js'
const process = childProcess.spawn('node', [cliExecPath])
Copy the code

Why is it better? The program.js source code starts with the Unix-like Shebang notation, however Windows does not know how to interpret this notation because Shebang is not a cross-platform standard.

This is also true for package.json scripts. Consider the following bad practice of defining NPM run scripts.

"scripts": {
  "postinstall": "myInstall.js"
}
Copy the code

This is because the Shebang in Mysume.js will not help Windows understand how to run this with the Node interpreter.

Instead, follow these best practices.

"scripts": {
  "postinstall": "node myInstall.js"
}
Copy the code

Shell interpreters vary from one to another

Not all characters are treated the same in different shell interpreters.

For example, the Windows command prompt treats single and double quotes differently, as expected on bash shells, so it does not recognize that the entire string inside a single quote belongs to the same string group, which results in an error.

This will fail in a Windows Node.js environment that uses the Windows command prompt.

package.json

"scripts": {
  "format": "prettier-standard '**/*.js'",
  ...
}
Copy the code

To solve this problem, make the NPM Run script really cross-platform between Windows, macOS, and Linux.

package.json

"scripts": {
  "format": "prettier-standard \"**/*.js\"",
  ...
}
Copy the code

In this case, we had to use double quotes and escape them with JSON symbols.

Avoid series paths

Paths are built differently on different platforms. When they are built manually by concatenating strings, they are necessarily not interoperable across different platforms.

Let’s look at an example of a bad habit.

const
Copy the code

It assumes that forward slashes are path separators, whereas in Windows, for example, backslashes are used.

Rather than build file system paths manually, hand them over to Node.js’s own path module.

const
Copy the code

Avoid concatenating commands with semicolons

Linux shells are known to support semicolons (;) To connect commands in order to run them, for example: CD/TMP; Ls. However, doing the same thing on Windows will fail.

Avoid doing the following.

const
Copy the code

Instead, use a double amp or double pipe symbol.

const
Copy the code

3.4 Setting priorities

✅ ** do: ** Allows configuration to be obtained from multiple sources, in priority order. Command line arguments have the highest priority, followed by shell variables, followed by different levels of configuration.

** Otherwise: ** Users face frustration in customizing their CLI experience.

ℹ ️ details

Detect and support configuration Settings using environment variables, as this will be a common way to modify the behavior of invoked CLI applications in many toolchains.

The configuration priorities of command line applications should follow the following points.

  • Command line arguments specified when the application is invoked.
  • Environment variables for the generated shell, and any other environment variables available to the application.
  • Project scope configuration, such as local directory.git/configFile.
  • User scope configuration, for example: user home directory configuration file:~/.gitconfigOr its XDG equivalent:~/.config/git/config
  • System-wide configuration, for example:/etc/gitconfig

Reference project.

  • cosmiconfig

4 Accessibility

This section discusses best practices for making a Node.js CLI application available to users who want to use it but lack an environment in which maintainers designed the application.

In this section.

  • 4.1 Containerizing the CLI
  • 4.2 Graceful Degradation
  • 4.3Node.js Versions Compatible
  • 4.4Shebang automatically detects the runtime of Node.js

4.1 Containerizing the CLI

✅ ** Do: ** Create a Docker image for the CLI and publish it to a public registry like Docker Hub so that users who don’t have a Node.js environment can use it.

** Otherwise: ** Users without a Node.js environment will have no NPM or NPX and therefore will not be able to run your CLI application.

ℹ️ Details

Installing node.js CLI applications from the NPM registry usually uses the Node.js native toolchain, such as NPM or NPX. These are commonly used by JavaScript and Node.js developers and are expected to be referenced in the installation instructions.

However, if your goal is to make CLI applications available to the general public, regardless of whether they are familiar with JavaScript or have such tools, then distributing your CLI applications only as an installation of the NPM registry will be limited. If your CLI application is intended to be used in a build or CI environment, these may also require installation of Node.js-related toolchain dependencies.

There are many ways to package and distribute executables, and having them as Docker containers, pre-bundled with your CLI application, is an easy-to-consume alternative with no dependencies (other than requiring a Docker environment).

4.2 Graceful Degradation

✅ ** Does: ** provides users with the ability to opt out of color and animation-rich displays in unsupported environments, such as skipping interactivity and providing formatted output as JSON.

** Otherwise: ** For users without supported terminals, having color output, using terminal interactions such as prompts, and other rich display interfaces can significantly reduce the end user experience and make them reluctant to use your CLI application.

ℹ ️ details

It is common to provide rich forms of terminal display, such as color output, ASCII charts, and even animation, on top of terminals and powerful prompt mechanisms. This may be helpful for a good user experience for those who have a supported terminal, whereas for those who don’t, it can be garbled or completely unusable.

To enable users who do not support terminals to use the Node.js CLI application correctly, you can choose.

  • Automatically detects terminal capabilities and evaluates whether to reduce CLI interactivity at run time
  • Provide an option that lets the user explicitly switch an elegant degradation, for example by providing one--jsonCommand line arguments to force it to output raw data.
👍  Tip

  Supporting graceful degradation such as JSON output isn't only useful for
  end-users and their unuspported terminals, but is also valuable for running
  in continuous integration environments, as well as enabling users
  the ability to connect your program's output with other program's input or
  export data if needed.
Copy the code

4.3 Compatibility with Node.js Versions

✅ ** Do: ** For supported and maintained versions of Node.js.

** Otherwise: ** Codebases that try to remain compatible with older and unsupported Versions of Node.js will be difficult to maintain and lose the benefits of language and runtime features.

ℹ ️ details

Sometimes you may need to specifically target older versions of Node.js that lack the new features of ECAMScript. For example, if you’re building a Node.js CLI primarily for DevOps or IT, they may not have an ideal Node.js environment and the latest runtime. For reference, Debian Stretch (Oldstable) ships with Node.js 8.11.1.

If you do need to target older versions of Node.js, such as Node.js 8, 6, or 4, which are final releases, it is best to use a translator, such as Babel, to ensure that the generated code matches versions of the V8 JavaScript engine and their Node.js runtime.

Another workaround is to provide a containerized version of the CLI to avoid the old target. See section (4.1) containerizing the CLI.

Don’t dumb up your program code by using an old ECMAScript language specification that matches an unmaintained or EOL Node.js version, as this will only cause code maintenance problems.

If the CLI is called I an unsupported environment, try to detect it and exit with a descriptive error message to present a friendly and informative error message. Look at the example of Dockly.

4.4 Shebang automatically detects the runtime of Node.js

✅ ** Do: ** Use an installation-independent reference in your Shebang declaration to automatically locate the runtime of Node.js based on the runtime environment, such as #! The/usr/bin/env node.

** Otherwise: ** Use hard-coded Node.js runtime locations such as #! /usr/local/bin/node, which is specific to your own environment, may render the Node.js CLI inoperable in other node.js locations.

ℹ ️ details

Developing the Node.js CLI might be a simple start by running the entry file nodecli.js and then adding #! To the top of the cli.js file. /usr/local/bin/node, however, is still a flawed method because the location of the Node executable is not guaranteed for other users’ environments.

It should be noted that specifying #! /usr/bin/env node is the best practice, again assuming that the Node.js runtime is referred to as node, not nodejs or something else.

5 test

In this section.

  • 5.1 Distrust locales

5.1 Distrust locales

✅ ** do: ** Do not assume that the output text is equal to the string you assert, as the test may be run on a different system than your language, or the default language of English.

** Otherwise: ** Developers will encounter test failures because they are testing on a different system than the English default.

ℹ ️ details

When you choose to test the CLI by running the CLI and parsing the output, you may prefer to grep specific features to make sure they are present in the output, such as providing examples correctly when the CLI runs with no parameters.

const
Copy the code

If your CLI parameter resolution library supports automatic detection of locales and adoption of locales when tests will be run on non-English based locales, tests like this will fail because languages ranging from Examples to local equivalents are set as the default locale on the system.

6 error

The best practices covered in this section relate to making the Node.js CLI application available to users who want to use it, but lack an ideal environment for maintainers to design the application.

In essence, the goal of the best practices described in this section is to help users troubleshoot errors quickly and easily without having to consult documentation or source code to understand them.

In this section.

  • 6.1 Traceable errors
  • 6.2 Operable errors
  • 6.3 Debugging mode
  • 6.4 Use exit codes correctly
  • 6.5 Effortless error reporting

6.1 Traceable errors

✅ ** Do: ** When reporting errors, provide traceable error codes that can be found in the project’s documentation and simplify troubleshooting of error messages.

If possible, extend traceable error code with further information so that it can be easily parsed and the context is clear.

❌ ** Otherwise: ** Common error messages are often vague, making it difficult for users to search for solutions. Parsing and analysis are not as straightforward, and referencing them in documentation is not as clean.

ℹ ️ details

Be sure to include a reference number or a specific error code when returning the error message so you can look it up later. Just like HTTP status codes, CLI applications require naming or encoding errors.

Example.

$ my-cli-tool --doSomething

Error (E4002): please provide an API token via environment variables
Copy the code

6.2 Operable errors

✅ ** do: ** A failed error message should tell the user what is needed as a fix, not complain about having an error.

** Otherwise: ** Users may not be able to use your CLI application successfully if they are not prompted to take action to resolve the error message.

ℹ ️ details

Example.

$ my-cli-tool --doSomething

Error (E4002): please provide an API token via environment variables
Copy the code

6.3 Debugging mode

✅ ** Do: ** Allow advanced users to enable more detailed information if problems need to be diagnosed.

** Otherwise: ** Do not skip debugging. This makes it harder to gather feedback from users and to find out what went wrong.

ℹ ️ details

Use environment variables and command-line arguments to enable the extended Debug Verbosity level. Include debug messages in your code where it makes sense to help users and maintainers understand program flow, inputs and outputs, and other information to make problem solving easier.

📦 Recommended software package

Refer to the source Node.js software package.

  • debug

6.4 Use exit codes correctly

✅ ** Do it: ** Terminate your program with the correct exit code that communicates the semantics of the error or exit status.

** Otherwise: ** Incorrect or missing exit code will hinder the use of your CLI in continuous integration processes and other command-line script use cases.

ℹ ️ details

Command-line scripts often make use of the shell’s $? To infer the program’s status code and take action based on it. This is also used in continuous integration (CI) processes to determine whether a step completed successfully.

If your CLI always terminates without a specific status code, even on errors, the shell and other programs that rely on it have no way of knowing that. You should communicate this when an error occurs that causes your program to terminate. For example.

try
Copy the code

A brief reference to the exit code.

  • Exit code 0 indicates successful execution
  • Exit code 1 represents a failure.

You can also choose to use custom exit codes with the semantics of your program, but if you do, be sure to record them correctly.

Reference. A list of exit codes used by the BASH shell

6.5 Effortless error reporting

✅ ** Do it: ** Make it easy to submit error reports by providing a URL to open the problem and presetting the required data as much as possible. Question templates, such as GitHub, can further guide users on what information is necessary.

** Otherwise: ** Users get frustrated when searching for how to report errors and may end up with little useful information or not submit problems at all.

7 development

This section covers development and maintenance best practices for building Node.js command-line applications.

In this section.

  • 7.1 Using the bin Object
  • 7.2 Using a Relative Path
  • 7.3 Using File Fields

7.1 Using the bin Object

✅ ** do: ** Use an object to define the name of the executable file and its path.

** Otherwise: ** You will couple the package name with the executable.

ℹ ️ details

The package.json below shows an example of decoupling the name of an executable from the filename and its location in the project.

  
Copy the code

7.2 Using a Relative Path

✅ ** Do: ** use process.cwd() to access user input paths and __dirname to access project-based paths.

** Otherwise: ** You will get an incorrect file path and will not be able to access the file.

ℹ ️ details

You may find yourself needing to access files within the scope of the project file, or files entered by the user, such as logs, JSON files, or other files. Confusing the use of process.cwd() or __dirname will result in errors and will also result in not using either method.

How to access files properly.

  • process.cwd()This can be used when the file path you need to access depends on the relative location of the Node.js CLI. A good example of this is when the CLI supports file paths to create logs, for example:myCli --outfile .. /.. /out.json. ifmyCliInstalled in the/usr/local/node_modules/myCli/bin/myCli.js, thenprocess.cwd()Will not point to this location, but to the current working directory, that is, whatever directory the user was in when he invoked the CLI.
  • __dirname: This is used when you need to access a file from the CLI source code and reference a file from the location of the file where the code resides. For example, when the CLI needs to access JSON data files in another directory:fs.readFile(path.join(__dirname, '.. ', 'myDataFile.json'))

7.3 the use offilesfield

✅ ** Do: ** Use the files field to include only the necessary files in the packages you distribute.

** Otherwise: ** You will get a package containing files that may not need to run your CLI application. For example (test files, development configuration, etc.).

ℹ️ Details

To keep the package size of the distribution small, we should include only the files needed to run the CLI application. See this post for more details.

The following files field tells NPM that the CLI includes all files in the SRC directory except the spec files.

"files"
Copy the code

The author

Node.js CLI Application Best Practices ©Liran Tal, distributed under a CC BY-SA 4.0 license.

This project follows the specifications of all contributors. Any form of contribution is welcome!

license

This work is licensed under the Creative Commons Attribution – Share alike 4.0 International License.