diff --git a/package.json b/package.json
index e912ba893b316bba19bdc9cafad19d21ee861d6c..9cf2f50f14f3b68b382a67bc384d7a7035445a41 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
   "scripts": {
     "build": "node packages/react-scripts/scripts/build.js",
     "changelog": "lerna-changelog",
-    "create-react-app": "tasks/cra.sh",
+    "create-react-app": "node tasks/cra.js",
     "e2e": "tasks/e2e-simple.sh",
     "e2e:docker": "tasks/local-test.sh",
     "postinstall": "node bootstrap.js && cd packages/react-error-overlay/ && npm run build:prod",
diff --git a/tasks/cra.js b/tasks/cra.js
new file mode 100644
index 0000000000000000000000000000000000000000..ec15d702ac517357cb8bac74a5bd7d0b60d92093
--- /dev/null
+++ b/tasks/cra.js
@@ -0,0 +1,109 @@
+#!/usr/bin/env node
+/**
+ * Copyright (c) 2015-present, Facebook, Inc. 
+ * 
+ * This source code is licensed under the MIT license found in the 
+ * LICENSE file in the root directory of this source tree. 
+ */
+
+'use strict';
+
+const fs = require('fs');
+const path = require('path');
+const cp = require('child_process');
+
+const cleanup = () => {
+  console.log('Cleaning up.');
+  // Uncomment when snapshot testing is enabled by default:
+  // rm ./template/src/__snapshots__/App.test.js.snap
+};
+
+const handleExit = () => {
+  cleanup();
+  console.log('Exiting without error.');
+  process.exit();
+};
+
+const handleError = e => {
+  console.error('ERROR! An error was encountered while executing\n', e);
+  cleanup();
+  console.log('Exiting with error.');
+  process.exit(1);
+};
+
+process.on('SIGINT', handleExit);
+process.on('uncaughtException', handleError);
+
+// ******************************************************************************
+// Pack react- scripts so we can verify they work.
+// ******************************************************************************
+
+const rootDir = path.join(__dirname, '..');
+const reactScriptsDir = path.join(rootDir, 'packages', 'react-scripts');
+const packageJsonPath = path.join(reactScriptsDir, 'package.json');
+const packageJsonOrigPath = path.join(reactScriptsDir, 'package.json.orig');
+
+// Install all our packages
+const lernaPath = path.join(rootDir, 'node_modules', '.bin', 'lerna');
+cp.execSync(`${lernaPath} bootstrap`, {
+  cwd: rootDir,
+  stdio: 'inherit',
+});
+
+// Save package.json because we're going to touch it
+fs.writeFileSync(packageJsonOrigPath, fs.readFileSync(packageJsonPath));
+
+// Replace own dependencies (those in the`packages` dir) with the local paths
+// of those packages
+const replaceOwnDepsPath = path.join(__dirname, 'replace-own-deps.js');
+cp.execSync(`node ${replaceOwnDepsPath}`, { stdio: 'inherit' });
+
+// Finally, pack react-scripts
+// Don't redirect stdio as we want to capture the output that will be returned
+// from execSync(). In this case it will be the .tgz filename.
+const scriptsFileName = cp
+  .execSync(`npm pack`, { cwd: reactScriptsDir })
+  .toString()
+  .trim();
+const scriptsPath = path.join(
+  rootDir,
+  'packages',
+  'react-scripts',
+  scriptsFileName
+);
+
+// Restore package.json
+fs.unlinkSync(packageJsonPath);
+fs.writeFileSync(packageJsonPath, fs.readFileSync(packageJsonOrigPath));
+fs.unlinkSync(packageJsonOrigPath);
+
+// ******************************************************************************
+// Now that we have packed them, call the global CLI.
+// ******************************************************************************
+
+// If Yarn is installed, clean its cache because it may have cached react-scripts
+try {
+  cp.execSync('yarn cache clean');
+} catch (e) {
+  // We can safely ignore this as the user doesn't have yarn installed
+}
+
+const args = process.argv.slice(2);
+
+// Now run the CRA command
+const craScriptPath = path.join(
+  rootDir,
+  'packages',
+  'create-react-app',
+  'index.js'
+);
+cp.execSync(
+  `node ${craScriptPath} --scripts-version="${scriptsPath}" ${args.join(' ')}`,
+  {
+    cwd: rootDir,
+    stdio: 'inherit',
+  }
+);
+
+// Cleanup
+handleExit();
diff --git a/tasks/cra.sh b/tasks/cra.sh
deleted file mode 100755
index 7929cdbf5af7e6532639e188aecebb5841419e98..0000000000000000000000000000000000000000
--- a/tasks/cra.sh
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2015-present, Facebook, Inc.
-#
-# This source code is licensed under the MIT license found in the
-# LICENSE file in the root directory of this source tree.
-
-# ******************************************************************************
-# This creates an app with the global CLI and `react-scripts` from the source.
-# It is useful for testing the end-to-end flow locally.
-# ******************************************************************************
-
-# Start in tasks/ even if run from root directory
-cd "$(dirname "$0")"
-
-function cleanup {
-  echo 'Cleaning up.'
-  # Uncomment when snapshot testing is enabled by default:
-  # rm ./template/src/__snapshots__/App.test.js.snap
-}
-
-# Error messages are redirected to stderr
-function handle_error {
-  echo "$(basename $0): ERROR! An error was encountered executing line $1." 1>&2;
-  cleanup
-  echo 'Exiting with error.' 1>&2;
-  exit 1
-}
-
-function handle_exit {
-  cleanup
-  echo 'Exiting without error.' 1>&2;
-  exit
-}
-
-# Exit the script with a helpful error message when any error is encountered
-trap 'set +x; handle_error $LINENO $BASH_COMMAND' ERR
-
-# Cleanup before exit on any termination signal
-trap 'set +x; handle_exit' SIGQUIT SIGTERM SIGINT SIGKILL SIGHUP
-
-# Echo every command being executed
-set -x
-
-# Go to root
-cd ..
-root_path=$PWD
-
-# ******************************************************************************
-# Pack react-scripts so we can verify they work.
-# ******************************************************************************
-
-# Install all our packages
-"$root_path"/node_modules/.bin/lerna bootstrap
-
-cd packages/react-scripts
-
-# Save package.json because we're going to touch it
-cp package.json package.json.orig
-
-# Replace own dependencies (those in the `packages` dir) with the local paths
-# of those packages.
-node "$root_path"/tasks/replace-own-deps.js
-
-# Finally, pack react-scripts
-scripts_path="$root_path"/packages/react-scripts/`npm pack`
-
-# Restore package.json
-rm package.json
-mv package.json.orig package.json
-
-
-# ******************************************************************************
-# Now that we have packed them, call the global CLI.
-# ******************************************************************************
-
-# If Yarn is installed, clean its cache because it may have cached react-scripts
-yarn cache clean || true
-
-# Go back to the root directory and run the command from here
-cd "$root_path"
-node packages/create-react-app/index.js --scripts-version="$scripts_path" "$@"
-
-# Cleanup
-cleanup