diff --git a/.gitignore b/.gitignore
index 12190558f14c6997086dd9ccd25f5a092f477d92..0a1354a9d1524148e83afd7b81005892be3aeaee 100644
--- a/.gitignore
+++ b/.gitignore
@@ -68,6 +68,7 @@ TODO.txt
 temp.*
 *.temp
 src/002-config/fc-version.js.commitHash.js
+devTools/scripts/.package.json.diff
 
 # macOS devices
 *.icloud
diff --git a/compile-legacy.bat b/compile-legacy.bat
index 448dc9c4eb402913250aa1fac9a46f7c4838fa2a..806bcf8d3d6b6c2856dba7e089ad49ffbbb8db37 100644
--- a/compile-legacy.bat
+++ b/compile-legacy.bat
@@ -122,4 +122,4 @@ ECHO --extramem: passed to sort (as SORT_MEM) in devTools/concatFiles.bat
 :: exit
 ENDLOCAL
 popd
-exit /b 0
\ No newline at end of file
+exit /b 0
diff --git a/compile.bat b/compile.bat
index 5dbdc2df58bb4d0dde14f31c0f206b47e65dd38b..5f62b8f6dff94da2a33acb4c621d01e5f922671c 100644
--- a/compile.bat
+++ b/compile.bat
@@ -1,83 +1,37 @@
-@echo off
+@ECHO off
 :: Free Cities Compiler - Windows
 
-:: Set working directory
-pushd %~dp0
-SET BASEDIR=%~dp0
-SETLOCAL EnableDelayedExpansion
-
-set "GULP=True"
-
-:: process arguments from command line
-:processargs
-SET ARG=%1
-IF DEFINED ARG (
-	:: disable building with Gulp
-	if "%ARG%"=="--legacy" SET "GULP="
-    SHIFT
-    GOTO processargs
-)
-
-:: check if gulp is defined
-if DEFINED GULP (
-	:: check for git
-	where /q git
-	IF ERRORLEVEL 1 (
-		ECHO git is not available.
-		SET "GULP="
-	)
-
-	:: check for node
-	where /q node
-	IF ERRORLEVEL 1 (
-		ECHO Node is not available.
-        SET "GULP="
-	)
-
-	:: if gulp is still defined
-	IF DEFINED GULP (
-		:: if the node_modules directory doesn't exist
-		IF NOT EXIST .\node_modules\ (
-			ECHO Node and git are available, but the Node modules are not installed.
-			CHOICE /C YN /N /M "Would you like us to run 'npm install' to install Node modules, using ~120 MB of disk space [Y/N]?"
-			IF !errorlevel!==1 (
-				ECHO Installing Node modules...
-				CALL npm install
-			) ELSE (
-				ECHO Use the '--legacy' flag to remove this prompt or run 'compile-legacy.bat' instead.
-				SET "GULP="
-			)
-		)
-	)
-
-	:: if gulp is still defined
-	if DEFINED GULP (
-		ECHO Using Gulp to build FC.
-		ECHO Pass the '--legacy' flag to use the legacy compiler or run 'compile-legacy.bat' instead.
-
-		:: execute gulp command
-		CALL npx gulp all --color
-
-		:: keep window open instead of closing it
-		<nul set /p "=Press any key to exit"
-		pause >nul
-
-		:: exit
-		ENDLOCAL
-		popd
-		exit /b 0
-    )
+:: run dependencyCheck.bat
+CALL .\devTools\scripts\dependencyCheck.bat
+SET CODE=%ERRORLEVEL%
+
+IF %CODE% EQU 69 (
+	:: if exit code is 69, then we don't have all the dependencies we need
+	:: fall back to legacy compiler
+	ECHO.
+	ECHO Dependencies not met, falling back to legacy compiler.
+    ECHO Run the legacy compiler directly to bypass these messages.
+    ECHO.
+    :: run compile-legacy.sh, passing all arguments to it
+	CALL ./compile-legacy.bat %*
+	EXIT /b 0
+) ELSE IF %CODE% EQU 0 (
+	:: if exit code is 0, run new compiler passing all arguments to it
+	ECHO.
+	ECHO Using new compiler, run 'compile-legacy.bat' instead to use the legacy compiler.
+	ECHO.
+	CALL npx gulp all --color %*
+	:: keep window open instead of closing it
+	<nul set /p "=Press any key to exit"
+	pause >nul
+	EXIT /b 0
+) ELSE (
+	:: if exit code is not 0, print error message and then attempt to fall back to legacy compiler
+	ECHO.
+	ECHO dependencyCheck.bat exited with code: %CODE%
+	ECHO Dependency check failed unexpectedly, falling back to legacy compiler.
+    ECHO Run the legacy compiler directly to bypass these messages.
+    ECHO.
+	CALL ./compile-legacy.bat %*
+    EXIT /b 0
 )
-
-ECHO.
-ECHO Development builds will be more debugable (will include source maps) if you enable Gulp.
-ECHO To enable Gulp make sure you have git and Node installed.
-ECHO To remove these messages, pass the '--legacy' flag or run 'compile-legacy.bat' instead.
-ECHO.
-
-:: Using legacy compiler since the '--legacy' flag was set or depenencies were missing.
-CALL compile-legacy.bat
-:: exit
-ENDLOCAL
-popd
-exit /b 0
\ No newline at end of file
diff --git a/compile.sh b/compile.sh
index 254fb9166ace184d563d2abe3fd3b93df00fc43c..171fd7c3020431a8a82495c3d31d83a7ee25297e 100755
--- a/compile.sh
+++ b/compile.sh
@@ -1,84 +1,32 @@
 #!/bin/bash
 
-# check for git
-if command -v git &> /dev/null; then
-    git="true"
-fi
-
-# check for Node
-if command -v node &> /dev/null; then
-    node="true"
-fi
-
-# check for node_modules
-if [[ "$git" && "$node" ]]; then
-    # if the node_modules directory doesn't exist
-    if [[ -d node_modules ]]; then
-        npm="true"
-    fi
-fi
-
-# displays help text
-function displayHelp() {
-	cat <<HelpText
-Usage: compile.sh [GULP FLAGS]
-
-Falls back to ./compile-legacy.sh if Gulp's dependencies are missing.
-
-HelpText
-
-if [[ $"npm" ]]; then
-    npx gulp
-else
-    cat <<HelpText
-Gulp's dependencies are not installed.
-HelpText
-fi
-}
-
-flags="all"
-
-if [[ "$1" == "" ]]; then
-	#tip if no option
-	echo "For more options see compile.sh -h."
-else
-	#parse options
-	while [[ "$1" ]]; do
-		case $1 in
-			-h | --help)
-				displayHelp
-				exit 0
-				;;
-			*)
-                flags="${flags} $1"
-		esac
-		shift
-	done
-fi
-
-echo ""
-if [[ ! "$git" ]]; then
-    echo "git is not available, install it to use Gulp compiler."
-fi
-
-if [[ ! "$node" ]]; then
-    echo "Node is not available, install it to use the Gulp compiler."
-fi
-
-if [[ ! "$npm" ]]; then
-    echo "Node modules aren't installed, run 'npm install' to install them."
-fi
-
-if [[ ! "$git" || ! "$node" || ! "$npm" ]]; then
+# Free Cities Compiler - Unix
+
+# run dependencyCheck.sh
+./devTools/scripts/dependencyCheck.sh
+exitCode=$?
+# exit code is now stored in $exitCode
+
+# if exit code is 69, then we don't have all the dependencies we need
+# fall back to legacy compiler
+if [[ $exitCode -eq 69 ]]; then
+    echo "Dependencies not met, falling back to legacy compiler."
+    echo "Run the legacy compiler directly to bypass these messages."
     echo ""
-    echo "Gulp compiler dependencies not met, falling back to legacy compiler."
-    echo "The legacy compiler is missing source map generation, but requires no other dependencies."
-    echo "If you wish to always use the legacy compiler, run './compile-legacy.sh' instead."
+    # run compile-legacy.sh, passing all arguments to it
+   ./compile-legacy.sh "$@"
+   exit 0
+# if exit code is not 0, print error message and then attempt to fall back to legacy compiler
+elif [[ $exitCode -ne 0 ]]; then
+    echo "Dependency check failed unexpectedly, falling back to legacy compiler."
+    echo "Run the legacy compiler directly to bypass these messages."
     echo ""
-    ./compile-legacy.sh $flags
+    # run compile-legacy.sh, passing all arguments to it
+   ./compile-legacy.sh "$@"
     exit 0
+# if exit code is 0, run new compiler passing all arguments to it
+else
+    echo "Using new compiler, run 'compile-legacy.sh' instead to use the legacy compiler."
+    echo ""
+    npx gulp all "$@"
 fi
-
-echo "Compiling using Gulp with these arguments: $flags"
-echo ""
-npx gulp $flags
\ No newline at end of file
diff --git a/devTools/scripts/dependencyCheck.bat b/devTools/scripts/dependencyCheck.bat
new file mode 100644
index 0000000000000000000000000000000000000000..6ba6b6375ee1aef7179856fdc7d5d4a17d207b8b
--- /dev/null
+++ b/devTools/scripts/dependencyCheck.bat
@@ -0,0 +1,161 @@
+@ECHO off
+
+:: Checks dependencies and prompts the user to install them (using winget) if missing.
+:: If winget is not installed falls back to printing info
+:: Returns exit code 69 :) if dependencies still don't exist at end of execution
+:: checks for git and node
+
+:: If you make a change to the functionality of this script you should also make sure to add the same functionality to 'dependencyCheck.sh'
+
+SETLOCAL EnableDelayedExpansion
+
+:: Set working directory
+SET BASEDIR=%~dp0
+
+:: check for dependencies
+where /q git
+IF %ERRORLEVEL% EQU 0 SET git="true"
+
+where /q node
+IF %ERRORLEVEL% EQU 0 SET node="true"
+
+IF DEFINED git (
+	:: And this is why I hate batch, nested if statements just to do an and operation
+	IF DEFINED node (
+		CALL :modulesCheck
+		EXIT /b !ERRORLEVEL!
+	)
+)
+
+:: Otherwise prompt the user
+ECHO This project has some optional dependencies that enable features that we believe will make the development process easier and more fruitful.
+ECHO You are seeing this because some or all of these dependencies are missing.
+ECHO If you wish to no longer see this, please use the legacy compiler. 'compile-legacy.bat'
+ECHO.
+ECHO Here is a list of the packages that are missing:
+
+IF NOT DEFINED git CALL :gitMessage
+
+IF NOT DEFINED node CALL :nodeMessage
+
+:: check for winget
+where /q winget
+IF ERRORLEVEL 1 (
+	CALL :manualInstall
+	EXIT /b !ERRORLEVEL!
+)
+
+ECHO.
+ECHO Should the packages listed above be installed automatically using the Windows package manager?
+ECHO Administrator access may be required to install these packages.
+ECHO If you do not want us to install these dependencies automatically, decline and the required commands will be printed out to do so manually.
+
+:: ask for confirmation
+CHOICE /C YN /N /M "Continue with the automatic installation? [Y/N]?"
+IF %ERRORLEVEL% EQU 1 (
+	CALL :automaticInstall
+	EXIT /b !ERRORLEVEL!
+) ELSE (
+	CALL :manualInstall
+	EXIT /b !ERRORLEVEL!
+)
+
+:: we should never hit this exit code
+ECHO Code should have never gotten here!!!
+EXIT /B 2
+
+:gitMessage
+ECHO   git, https://git-scm.com/, needed to interact with the .git folder in this project.
+ECHO     Allows for things like:
+ECHO       Keeping multiple compiled versions of FC based of the commit they were compiled with.
+ECHO       The legacy sanity checks have this as a hard dependency.
+GOTO :eof
+
+:nodeMessage
+ECHO   Node.js, https://nodejs.org/, enables all of the new sanity checks and the new compiler.
+ECHO     Allows for things like:
+ECHO       Source maps for easier debugging: https://dzone.com/articles/what-are-source-maps-and-how-to-properly-use-them
+ECHO       Javascript linting to catch bugs early using ESLint, https://eslint.org/
+:: TODO: @franklygeorge: update as we add the rest of the features
+GOTO :eof
+
+:modulesCheck
+:: if node_modules doesn't exist
+IF NOT EXIST node_modules (
+	ECHO.
+	ECHO All optional dependencies are install, but the Node modules are not installed.
+	ECHO.
+	ECHO These packages should take up less than 500MB of disk space. ~120 MB at time of writing.
+	ECHO They will be stored in the 'node_modules' directory inside of the project directory.
+	ECHO.
+	CHOICE /C YN /N /M "Would you like us to run 'npm install' to install them for you? [Y/N]?"
+	IF !ERRORLEVEL! EQU 1 (
+		CALL npm install
+		:: Save a hash of package.json for later comparison
+		CALL node .\devTools\scripts\dependencyCheck.js --diff-package --new-install
+		ECHO.
+	) ELSE (
+		ECHO.
+		EXIT /B 69
+	)
+) ELSE (
+	:: Compare current package.json hash with existing hash
+	CALL node .\devTools\scripts\dependencyCheck.js --diff-package
+)
+GOTO :eof
+
+:ensureDependenciesAndExit
+	:: wait for user input
+	<nul set /p "=Press any key to continue..."
+		pause >nul
+	ECHO.
+
+	:: check for dependencies
+	where /q git
+	IF %ERRORLEVEL% EQU 0 SET git="true"
+
+	where /q node
+	IF %ERRORLEVEL% EQU 0 SET node="true"
+
+	:: if no missing dependencies, exit with code 0, else exit with code 69
+	IF DEFINED git (
+		:: And this is why I hate batch, nested if statements and redundant code just to do an and operation
+		IF DEFINED node (
+			CALL :modulesCheck
+            EXIT /b !ERRORLEVEL!
+        ) ELSE (
+            ECHO.
+            EXIT /b 69
+		)
+	) ELSE (
+		ECHO.
+		EXIT /b 69
+	)
+GOTO :eof
+
+:manualInstall
+	:: prints out the info for manual installation
+    :: waits for user input
+    :: checks for dependencies
+    :: and then exits
+	ECHO.
+	ECHO To install these packages run the commands below.
+	ECHO.
+	ECHO "winget install --id=Git.Git -e  && winget install --id=OpenJS.NodeJS -e"
+	ECHO.
+	ECHO or download git from https://git-scm.com/download/win
+	ECHO and download Node.js from https://nodejs.org
+	ECHO.
+	ECHO You should install these packages now if you wish to do so.
+	CALL :ensureDependenciesAndExit
+	EXIT /b %ERRORLEVEL%
+GOTO :eof
+
+:automaticInstall
+	:: Install using winget
+	ECHO.
+	ECHO Executing "winget install --id=Git.Git -e  && winget install --id=OpenJS.NodeJS -e"
+	winget install --id=Git.Git -e  && winget install --id=OpenJS.NodeJS -e
+	CALL :ensureDependenciesAndExit
+	EXIT /b %ERRORLEVEL%
+GOTO :eof
diff --git a/devTools/scripts/dependencyCheck.js b/devTools/scripts/dependencyCheck.js
new file mode 100644
index 0000000000000000000000000000000000000000..befe3bf8a3b809e338a7eb0c68f009ad475e1dcf
--- /dev/null
+++ b/devTools/scripts/dependencyCheck.js
@@ -0,0 +1,75 @@
+/**
+ * @file does more complex dependency checks after Node.js exists.
+ * Currently just keeps track of wether or not package.json has changed
+ */
+
+import yargs from "yargs";
+import {hideBin} from "yargs/helpers";
+import jetpack from "fs-jetpack";
+import {ask} from "./yesno.js";
+import {execSync} from "child_process";
+
+const packageCopyLocation = "devTools/scripts/.package.json.diff";
+const packageLocation = "package.json";
+
+const args = yargs(hideBin(process.argv))
+	.showHelpOnFail(true)
+	.option('diff-package', {
+		type: 'boolean',
+		description: 'Hash package.json and compare it with past versions to detect changes.',
+		default: false,
+	})
+	.option('new-install', {
+		type: 'boolean',
+		description: 'Mark this as an new npm install',
+		default: false,
+	})
+	.parse();
+
+async function promptForUpdate() {
+	// TODO: @franklygeorge diff of changes if possible
+	const run = await ask({
+		question: "Run 'npm install' [Y/N]?"
+	});
+	if (run === true) {
+		console.log("Running 'npm install'...");
+		// run npm install
+		execSync("npm install", {stdio:[0, 1, 2]});
+		// copy packageLocation to packageCopyLocation
+		jetpack.copy(packageLocation, packageCopyLocation, {overwrite: true});
+	}
+}
+
+async function diffPackage() {
+	if (args.newInstall === true) {
+		// disregard any existing packageCopyLocation and copy package.json to packageCopyLocation
+		jetpack.copy(packageLocation, packageCopyLocation, {overwrite: true});
+	} else {
+		// check if packageCopyLocation exists
+		if (jetpack.exists(packageCopyLocation) === "file") {
+			// compare contents of packageCopyLocation and packageLocation
+			const copyContents = jetpack.read(packageCopyLocation, "json");
+			const packageContents = jetpack.read(packageLocation, "json");
+			if (JSON.stringify(copyContents)!== JSON.stringify(packageContents)) {
+				console.log("package.json has changed. 'npm install' should be ran to make sure the correct packages are installed.");
+				await promptForUpdate();
+			}
+		} else {
+			// There is already an install but it is not managed by this tool
+			// Treat like a package.json change but with slightly different messaging
+			console.log("We do not have the required data to make sure that the correct node packages are installed.");
+			console.log("We would like to run 'npm install' again to make sure everything is installed correctly.");
+			await promptForUpdate();
+		}
+	}
+}
+
+
+
+async function main() {
+	if (args.diffPackage === true) {
+		await diffPackage();
+	}
+}
+
+await main();
diff --git a/devTools/scripts/dependencyCheck.sh b/devTools/scripts/dependencyCheck.sh
new file mode 100755
index 0000000000000000000000000000000000000000..11cda4375c88a28c19db0d03f5c29a41291af0ab
--- /dev/null
+++ b/devTools/scripts/dependencyCheck.sh
@@ -0,0 +1,203 @@
+#!/bin/bash
+
+# Checks dependencies and prompts the user to install them if missing.
+# Returns exit code 69 :) if dependencies still don't exist at end of execution
+# checks for git and node
+
+# If you make a change to the functionality of this script you should also make sure to add the same functionality to 'dependencyCheck.bat'
+
+aptInstall="sudo apt-get install git nodejs"
+pacmanInstall="sudo pacman -S git nodejs"
+dnfInstall="sudo dnf install git nodejs"
+yumInstall="sudo yum install git nodejs"
+brewInstall="brew install git nodejs"
+
+function modulesCheck() {
+    # if node_modules doesn't exist
+    if [[ ! -d node_modules ]]; then
+        # ask user if we can install modules
+        echo ""
+        echo "All optional dependencies are install, but the Node modules are not installed."
+        echo ""
+        echo "These packages should take up less than 500MB of disk space. ~120 MB at time of writing."
+        echo "They will be stored in the 'node_modules' directory inside of the project directory."
+        echo ""
+        read -n 1 -p "Would you like us to run 'npm install' to install them for you? [Y/N]?" choice
+        case "$choice" in 
+        y|Y )
+            echo ""
+            npm install
+            # Save a hash of package.json for later comparison
+            node ./devTools/scripts/dependencyCheck.js --diff-package --new-install
+            echo ""
+            echo ""
+            ;;
+        * )
+            echo ""
+            echo ""
+            exit 69
+            ;;
+        esac
+    else
+    # Compare current package.json hash with existing hash
+	node ./devTools/scripts/dependencyCheck.js --diff-package
+    fi
+}   
+
+function ensureDependenciesAndExit() {
+    # wait for user input
+    read -n 1 -s -r -p "Press any key to continue..."
+    echo ""
+
+    # check for dependencies
+    if command -v git &> /dev/null; then
+        git="true"
+    fi
+
+    if command -v node &> /dev/null; then
+        node="true"
+    fi
+
+    # If no missing dependencies, exit with code 0, else exit with code 69
+    if [[ "$git" && "$node" ]]; then
+        modulesCheck
+        echo ""
+        echo ""
+        exit 0
+    else
+        echo ""
+        echo ""
+        exit 69
+    fi
+}
+
+function manualInstall() {
+    # prints out the info for manual installation
+    # waits for user input
+    # checks for dependencies
+    # and then exits
+    echo ""
+    echo ""
+    echo "To install these packages run the command below that applies to your system."
+    echo ""
+
+    echo "Ubuntu/Debian and derivatives:"
+    echo "  $aptInstall"
+
+    echo "Arch and derivatives:"
+    echo "  $pacmanInstall"
+
+    echo "Fedora/RHEL/CentOS and derivatives:"
+    # dnf
+    echo "  $dnfInstall"
+    # yum
+    echo "  or"
+    echo "  $yumInstall"
+
+    echo "Mac OS X:"
+    echo "  $brewInstall"
+
+    echo ""
+    echo "You should install these packages now if you wish to do so."
+    ensureDependenciesAndExit
+}
+
+function automaticInstall() {
+    # Install using $packageManager
+    echo ""
+    echo ""
+    if [[ "$packageManager" == "apt" ]]; then
+        echo "Executing '$aptInstall'"
+        $aptInstall
+    elif [[ "$packageManager" == "pacman" ]]; then
+        echo "Executing '$pacmanInstall'"
+        $pacmanInstall
+    elif [[ "$packageManager" == "dnf" ]]; then
+        echo "Executing '$dnfInstall'"
+        $dnfInstall
+    elif [[ "$packageManager" == "yum" ]]; then
+        echo "Executing '$yumInstall'"
+        $yumInstall
+    elif [[ "$packageManager" == "brew" ]]; then
+        echo "Executing '$brewInstall'"
+        $brewInstall
+    fi
+    ensureDependenciesAndExit
+}
+
+# Check for dependencies
+if command -v git &> /dev/null; then
+    git="true"
+fi
+
+if command -v node &> /dev/null; then
+    node="true"
+fi
+
+# If no missing dependencies, exit
+if [[ "$git" && "$node" ]]; then
+    modulesCheck
+    exit 0
+fi
+
+# Otherwise prompt the user
+echo "This project has some optional dependencies that enable features that we believe will make the development process easier and more fruitful."
+echo "You are seeing this because some or all of these dependencies are missing."
+echo "If you wish to no longer see this, please use one the legacy compiler. 'compile-legacy.sh'"
+echo ""
+echo "Here is a list of the packages that are missing:"
+
+if [[ ! "$git" ]]; then
+    echo "  git, https://git-scm.com/, needed to interact with the .git folder in this project."
+    echo "    Allows for things like:"
+    echo "      Keeping multiple compiled versions of FC based of the commit they were compiled with."
+    echo "      The legacy sanity checks have this as a hard dependency."
+fi
+
+if [[ ! "$node" ]]; then
+    echo "  Node.js, https://nodejs.org/, enables all of the new sanity checks and the new compiler."
+    echo "    Allows for things like:"
+    echo "      Source maps for easier debugging: https://dzone.com/articles/what-are-source-maps-and-how-to-properly-use-them"
+    echo "      Javascript linting to catch bugs early using ESLint, https://eslint.org/"
+    # TODO: @franklygeorge: update as we add the rest of the features
+fi
+
+# checks for apt, brew, dnf, yum, and pacman in that order
+# meaning that we need to check for them in reverse order
+if command -v pacman &> /dev/null; then
+    packageManager="pacman"
+fi
+
+if command -v yum &> /dev/null; then
+    packageManager="yum"
+fi
+
+if command -v dnf &> /dev/null; then
+    packageManager="dnf"
+fi
+
+if command -v brew &> /dev/null; then
+    packageManager="brew"
+fi
+
+if command -v apt-get &> /dev/null; then
+    packageManager="apt"
+fi
+
+# if no package manager
+if [[ ! "$packageManager" ]]; then
+    manualInstall
+fi
+
+echo ""
+echo "Should the packages listed above be installed automatically using the ${packageManager} package manager?"
+echo "You will likely be asked for your root/sudo password as it is often required to install new packages."
+echo "If you do not want us to install these dependencies automatically, decline and the required commands will be printed out to do so manually."
+
+# ask for confirmation
+read -n 1 -p "Continue with the automatic installation? [Y/N]?" choice
+case "$choice" in 
+  y|Y ) automaticInstall;;
+  n|N ) manualInstall;;
+  * ) manualInstall;;
+esac
\ No newline at end of file
diff --git a/devTools/scripts/yesno.js b/devTools/scripts/yesno.js
new file mode 100644
index 0000000000000000000000000000000000000000..53a33942caf65ef38005f096c5714df635a0c70f
--- /dev/null
+++ b/devTools/scripts/yesno.js
@@ -0,0 +1,62 @@
+'use strict';
+
+// Copied from https://github.com/tcql/node-yesno/blob/master/yesno.js
+// as to not have it as a node dependency
+
+// const readline = require('readline');
+import readline from "readline";
+
+
+const options = {
+    yes: [ 'yes', 'y' ],
+    no:  [ 'no', 'n' ]
+};
+
+
+function defaultInvalidHandler ({ question, defaultValue, yesValues, noValues }) {
+    var yValues = (yesValues || options.yes);
+    var nValues  = (noValues || options.no);
+
+    process.stdout.write('\nInvalid Response.\n');
+    process.stdout.write('Answer either yes : (' + yValues.join(', ') + ') \n');
+    process.stdout.write('Or no: (' + nValues.join(', ') + ') \n\n');
+}
+
+
+async function ask ({ question, defaultValue, yesValues, noValues, invalid }) {
+    if (!invalid || typeof invalid !== 'function')
+        invalid = defaultInvalidHandler;
+
+    var yValues = (yesValues || options.yes).map((v) => v.toLowerCase());
+    var nValues  = (noValues || options.no).map((v) => v.toLowerCase());
+
+    const rl = readline.createInterface({
+      input: process.stdin,
+      output: process.stdout
+    });
+
+    return new Promise(function (resolve, reject) {
+        rl.question(question + ' ', async function (answer) {
+            rl.close();
+
+            const cleaned = answer.trim().toLowerCase();
+
+            if (cleaned == '' && defaultValue != null)
+                return resolve(defaultValue);
+
+            if (yValues.indexOf(cleaned) >= 0)
+                return resolve(true);
+                
+            if (nValues.indexOf(cleaned) >= 0)
+                return resolve(false);
+    
+            invalid({ question, defaultValue, yesValues, noValues });
+            const result = await ask({ question, defaultValue, yesValues, noValues, invalid });
+            resolve(result);
+        });
+    });
+}
+
+
+// module.exports = ask;
+export {ask}