diff --git a/packages/react-dev-utils/openBrowser.js b/packages/react-dev-utils/openBrowser.js
index 3cd877a12a732b550ffcde98f7e0868b7545d2ce..a3623515e0a52ab9d03f9550c7cef45b84a0ca07 100644
--- a/packages/react-dev-utils/openBrowser.js
+++ b/packages/react-dev-utils/openBrowser.js
@@ -10,8 +10,32 @@
 var execSync = require('child_process').execSync;
 var opn = require('opn');
 
+// https://github.com/sindresorhus/opn#app
+var OSX_CHROME = 'google chrome';
+
 function openBrowser(url) {
-  if (process.platform === 'darwin') {
+  // Attempt to honor this environment variable.
+  // It is specific to the operating system.
+  // See https://github.com/sindresorhus/opn#app for documentation.
+  const browser = process.env.BROWSER;
+
+  // Special case: BROWSER="none" will prevent opening completely.
+  if (browser === 'none') {
+    return false;
+  }
+
+  // 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
+  // existing tab when possible instead of creating a new one.
+  const shouldTryOpenChromeWithAppleScript = (
+    process.platform === 'darwin' && (
+      typeof browser !== 'string' ||
+      browser === OSX_CHROME
+    )
+  );
+
+  if (shouldTryOpenChromeWithAppleScript) {
     try {
       // Try our best to reuse existing tab
       // on OS X Google Chrome with AppleScript
@@ -25,11 +49,12 @@ function openBrowser(url) {
       // Ignore errors.
     }
   }
+
   // Fallback to opn
   // (It will always open new tab)
   try {
-    var option = {app: process.env.BROWSER};
-    opn(url, option).catch(() => {}); // Prevent `unhandledRejection` error.
+    var options = {app: browser};
+    opn(url, options).catch(() => {}); // Prevent `unhandledRejection` error.
     return true;
   } catch (err) {
     return false;