diff --git a/core/package.json b/core/package.json
index 8bf4e79..ef3afb3 100644
--- a/core/package.json
+++ b/core/package.json
@@ -4,7 +4,7 @@
   "license": "GPL-2.0",
   "private": true,
   "scripts": {
-    "build:js": "./scripts/js/babel-es6-compile.sh",
+    "build:js": "node ./scripts/js/babel-es6-compile.js",
     "watch:js": "node ./scripts/js/babel-es6-watch.js"
   },
   "devDependencies": {
diff --git a/core/scripts/js/babel-es6-compile.js b/core/scripts/js/babel-es6-compile.js
new file mode 100644
index 0000000..78f0ac8
--- /dev/null
+++ b/core/scripts/js/babel-es6-compile.js
@@ -0,0 +1,59 @@
+/**
+ * @file
+ *
+ * Compile *.es6.js files to ES5.
+ *
+ * @internal This file is part of the core javascript build process and is only
+ * meant to be used in that context.
+ */
+
+'use strict';
+
+const fs = require('fs');
+const path = require('path');
+const babel = require('babel-core');
+const chokidar = require('chokidar');
+
+// Logging human-readable timestamp.
+const log = function (message) {
+  // eslint-disable-next-line no-console
+  console.log(`[${new Date().toTimeString().slice(0, 8)}] ${message}`);
+};
+
+function addSourceMappingUrl(code, loc) {
+  return code + '\n\n//# sourceMappingURL=' + path.basename(loc);
+}
+
+const fileMatch = './**/*.es6.js';
+const watcher = chokidar.watch(fileMatch, {
+  ignoreInitial: false,
+  ignored: 'node_modules/**'
+});
+
+const babelOptions = {
+  sourceMaps: true,
+  comments: false
+};
+
+const changedOrAdded = (filePath) => {
+  babel.transformFile(filePath, babelOptions, function (err, result) {
+    const fileName = filePath.slice(0, -7);
+
+    // we've requested for a sourcemap to be written to disk
+    let mapLoc = `${fileName}.js.map`;
+    result.code = addSourceMappingUrl(result.code, mapLoc);
+    fs.writeFileSync(mapLoc, JSON.stringify(result.map));
+
+    fs.writeFileSync(`${fileName}.js`, result.code);
+
+    log(`'${filePath}' has been compiled.`);
+  });
+};
+
+watcher
+  .on('add', filePath => changedOrAdded(filePath))
+  .on('change', filePath => changedOrAdded(filePath))
+  .on('ready', () => {
+    log('Finished!');
+    process.exit(0);
+  });
diff --git a/core/scripts/js/babel-es6-compile.sh b/core/scripts/js/babel-es6-compile.sh
deleted file mode 100644
index 174b337..0000000
--- a/core/scripts/js/babel-es6-compile.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-# Compile *.es6.js files to ES5.
-#
-# @internal This file is part of the core javascript build process and is only
-# meant to be used in that context.
-
-for js in `find ./{misc,modules,themes} -name '*.es6.js'`;
-do
-  ./node_modules/.bin/babel ${js} --out-file ${js%???????}.js --source-maps --no-comments
-done
