diff --git a/packages/react-dev-utils/openBrowser.js b/packages/react-dev-utils/openBrowser.js
index 8c97f723c4fc67cf1d7a8f875537af9dfffa4fec..15b7ad360a507c571dc6ed3f0789dd45ef8744cf 100644
--- a/packages/react-dev-utils/openBrowser.js
+++ b/packages/react-dev-utils/openBrowser.js
@@ -9,23 +9,61 @@
 
 'use strict';
 
+var chalk = require('chalk');
 var execSync = require('child_process').execSync;
+var spawn = require('cross-spawn');
 var opn = require('opn');
 
 // https://github.com/sindresorhus/opn#app
 var OSX_CHROME = 'google chrome';
 
-function openBrowser(url) {
+const Actions = Object.freeze({
+  NONE: 0,
+  BROWSER: 1,
+  SCRIPT: 2,
+});
+
+function getBrowserEnv() {
   // Attempt to honor this environment variable.
   // It is specific to the operating system.
   // See https://github.com/sindresorhus/opn#app for documentation.
-  var browser = process.env.BROWSER;
-
-  // Special case: BROWSER="none" will prevent opening completely.
-  if (browser === 'none') {
-    return false;
+  const value = process.env.BROWSER;
+  let action;
+  if (!value) {
+    // Default.
+    action = Actions.BROWSER;
+  } else if (value.toLowerCase().endsWith('.js')) {
+    action = Actions.SCRIPT;
+  } else if (value.toLowerCase() === 'none') {
+    action = Actions.NONE;
+  } else {
+    action = Actions.BROWSER;
   }
+  return { action, value };
+}
+
+function executeNodeScript(scriptPath, url) {
+  const extraArgs = process.argv.slice(2);
+  const child = spawn('node', [scriptPath, ...extraArgs, url], {
+    stdio: 'inherit',
+  });
+  child.on('close', code => {
+    if (code !== 0) {
+      console.log();
+      console.log(
+        chalk.red(
+          'The script specified as BROWSER environment variable failed.'
+        )
+      );
+      console.log(chalk.cyan(scriptPath) + ' exited with code ' + code + '.');
+      console.log();
+      return;
+    }
+  });
+  return true;
+}
 
+function startBrowserProcess(browser, url) {
   // If we're on OS X, the user hasn't specifically
   // requested a different browser, we can try opening
   // Chrome with AppleScript. This lets us reuse an
@@ -67,4 +105,23 @@ function openBrowser(url) {
   }
 }
 
+/**
+ * Reads the BROWSER evironment variable and decides what to do with it. Returns
+ * true if it opened a browser or ran a node.js script, otherwise false.
+ */
+function openBrowser(url) {
+  const { action, value } = getBrowserEnv();
+  switch (action) {
+    case Actions.NONE:
+      // Special case: BROWSER="none" will prevent opening completely.
+      return false;
+    case Actions.SCRIPT:
+      return executeNodeScript(value, url);
+    case Actions.BROWSER:
+      return startBrowserProcess(value, url);
+    default:
+      throw new Error('Not implemented.');
+  }
+}
+
 module.exports = openBrowser;
diff --git a/packages/react-dev-utils/package.json b/packages/react-dev-utils/package.json
index a5d4c75fe78a56e72d2b4fb3265ae269d117fc92..b33f200a09243421dd7117eaa1a5f6ce6098ba97 100644
--- a/packages/react-dev-utils/package.json
+++ b/packages/react-dev-utils/package.json
@@ -32,6 +32,7 @@
     "anser": "1.1.0",
     "babel-code-frame": "6.20.0",
     "chalk": "1.1.3",
+    "cross-spawn": "4.0.2",
     "escape-string-regexp": "1.0.5",
     "filesize": "3.3.0",
     "gzip-size": "3.0.0",
diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md
index f987de2f9ae8b37b66de4a68a0191ff00dfc553f..c178e573816ffdf6b1cc6f67f34f0daff3f5cdeb 100644
--- a/packages/react-scripts/template/README.md
+++ b/packages/react-scripts/template/README.md
@@ -1560,7 +1560,7 @@ You can adjust various development and production settings by setting environmen
 
 Variable | Development | Production | Usage
 :--- | :---: | :---: | :---
-BROWSER | :white_check_mark: | :x: | By default, Create React App will open the default system browser, favoring Chrome on macOS. Specify a [browser](https://github.com/sindresorhus/opn#app) to override this behavior, or set it to `none` to disable it completely.
+BROWSER | :white_check_mark: | :x: | By default, Create React App will open the default system browser, favoring Chrome on macOS. Specify a [browser](https://github.com/sindresorhus/opn#app) to override this behavior, or set it to `none` to disable it completely. <!-- TODO: enable with 0.10: If you need to customize the way the browser is launched, you can specify a node script instead. Any arguments passed to `npm start` will also be passed to this script, and the url where your app is served will be the last argument. Your script's file name must have the `.js` extension. -->
 HOST | :white_check_mark: | :x: | By default, the development web server binds to `localhost`. You may use this variable to specify a different host.
 PORT | :white_check_mark: | :x: | By default, the development web server will attempt to listen on port 3000 or prompt you to attempt the next available port. You may use this variable to specify a different port.
 HTTPS | :white_check_mark: | :x: | When set to `true`, Create React App will run the development server in `https` mode.