How to use Promise with exec in Node.js

Support for Promise in web browsers has come a long way, with only good old IE11 needing a polyfill to support it. According to the documentation at MDN, “the Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value”. The concept is similar to Observables (available in RxJs) and Future (Java). Together with async/await support being available in modern web browsers and the popular TypeScript programming language offering support even for older web browsers, it has become much easier to write asynchronous JavaScript code in a synchronous fashion without using external libraries.

If you are using Node.js directly or indirectly (e.g. through Electron), you can run shell commands in your application. For example, you can check in your Electron app if Java is installed. To do this using the shell, you’d run the java -version command. The exec function which is executed asynchronously can be used to run shell commands. However, if you want to wait for its result then it is becoming cumbersome: instead of returning a Promise, there is a callback. Callbacks are still useful in some cases but often, we can avoid getting into “callback hell” by using Promise.

For this purpose, I needed a way to use the exec function with Promise and async/await.

How to use Promise with exec in Node.js

  1. The function below wraps the exec statement in a Promise which is returned.
  2. Now you can either use Promise.then(). Alternatively, you can make your function async and use await to get the result directly.
* Executes a shell command and return it as a Promise.
* @param cmd {string}
* @return {Promise<string>}
function execShellCommand(cmd) {
const exec = require('child_process').exec;
return new Promise((resolve, reject) => {
exec(cmd, (error, stdout, stderr) => {
if (error) {
resolve(stdout? stdout : stderr);

Example usage: check if Java is installed on the device using Node

Here is some example code to check if Java is installed on a device using above function. We use await to get the result of the shell command and log it to the console.

const javaInfo = await execShellCommand('java -version');
/* Prints out:
java version "1.6.0_27"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0_27-b07)
Java HotSpot(TM) Client VM (build 1.6.0_27-b13, mixed mode, sharing)

You could argue why I am resolving either stdout or stderr. I am mainly using this function to check if certain things are installed on a device. While checking Java installation status returns stdout, checking Gradle installation status returns stderr even though stderr is the correct log result.


Thank you for reading this article. Promise is a great feature which enables JavaScript developers to write better asynchronous code in a synchronous matter. As you can easy, it is easy to wrap operations in Promises and waiting for the result. Thus, we can avoid getting into “callback hell” and keep our code cleaner.



Co-founder of Sunhat. Hiring software engineers in Europe. 有難うございます。🚀

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store