diff --git a/app/react/src/server/config/webpack.config.js b/app/react/src/server/config/webpack.config.js
index 72de95c5e61e..24eacd0bf24b 100644
--- a/app/react/src/server/config/webpack.config.js
+++ b/app/react/src/server/config/webpack.config.js
@@ -26,6 +26,7 @@ export default function() {
       new webpack.HotModuleReplacementPlugin(),
       new CaseSensitivePathsPlugin(),
       new WatchMissingNodeModulesPlugin(nodeModulesPaths),
+      new webpack.ProgressPlugin(),
     ],
     module: {
       rules: [
diff --git a/app/react/src/server/iframe.html.js b/app/react/src/server/iframe.html.js
index 240b2be5774e..580b48b6dec7 100644
--- a/app/react/src/server/iframe.html.js
+++ b/app/react/src/server/iframe.html.js
@@ -8,37 +8,47 @@ import url from 'url';
 //   'preview.0d2d3d845f78399fd6d5e859daa152a9.css',
 //   'static/preview.9adbb5ef965106be1cc3.bundle.js.map',
 //   'preview.0d2d3d845f78399fd6d5e859daa152a9.css.map' ]
-const previewUrlsFromAssets = assets => {
+const urlsFromAssets = assets => {
   if (!assets) {
     return {
-      js: 'static/preview.bundle.js',
+      js: ['static/preview.bundle.js'],
+      css: [],
     };
   }
 
-  if (typeof assets.preview === 'string') {
-    return {
-      js: assets.preview,
-    };
-  }
-
-  return {
-    js: assets.preview.find(filename => filename.match(/\.js$/)),
-    css: assets.preview.find(filename => filename.match(/\.css$/)),
+  const urls = {
+    js: [],
+    css: [],
   };
+
+  const re = /.+\.(\w+)$/;
+  Object.keys(assets)
+    // Don't load the manager script in the iframe
+    .filter(key => key !== 'manager')
+    .forEach(key => {
+      const asset = assets[key];
+      if (typeof asset === 'string') {
+        urls[re.exec(asset)[1]].push(asset);
+      } else {
+        const assetUrl = asset.find(u => re.exec(u)[1] !== 'map');
+        urls[re.exec(assetUrl)[1]].push(assetUrl);
+      }
+    });
+
+  return urls;
 };
 
 export default function(data) {
   const { assets, headHtml, publicPath } = data;
 
-  const previewUrls = previewUrlsFromAssets(assets);
+  const urls = urlsFromAssets(assets);
 
-  let previewCssTag = '';
-  if (previewUrls.css) {
-    previewCssTag = `<link rel='stylesheet' type='text/css' href='${url.resolve(
-      publicPath,
-      previewUrls.css
-    )}'>`;
-  }
+  const cssTags = urls.css
+    .map(u => `<link rel='stylesheet' type='text/css' href='${url.resolve(publicPath, u)}'>`)
+    .join('\n');
+  const scriptTags = urls.js
+    .map(u => `<script src="${url.resolve(publicPath, u)}"></script>`)
+    .join('\n');
 
   return `
     <!DOCTYPE html>
@@ -53,12 +63,12 @@ export default function(data) {
         </script>
         <title>Storybook</title>
         ${headHtml}
-        ${previewCssTag}
+        ${cssTags}
       </head>
       <body>
         <div id="root"></div>
         <div id="error-display"></div>
-        <script src="${url.resolve(publicPath, previewUrls.js)}"></script>
+        ${scriptTags}
       </body>
     </html>
   `;
diff --git a/app/react/src/server/index.js b/app/react/src/server/index.js
index d086222ebcbc..d23a75fb50f1 100755
--- a/app/react/src/server/index.js
+++ b/app/react/src/server/index.js
@@ -8,7 +8,7 @@ import path from 'path';
 import fs from 'fs';
 import chalk from 'chalk';
 import shelljs from 'shelljs';
-import storybook from './middleware';
+import storybook, { webpackValid } from './middleware';
 import packageJson from '../../package.json';
 import { parseList, getEnvConfig } from './utils';
 
@@ -135,11 +135,23 @@ process.env.STORYBOOK_GIT_BRANCH =
 // `getBaseConfig` function which is called inside the middleware
 app.use(storybook(configDir));
 
+let serverResolve = () => {};
+let serverReject = () => {};
+const serverListening = new Promise((resolve, reject) => {
+  serverResolve = resolve;
+  serverReject = reject;
+});
 server.listen(...listenAddr, error => {
   if (error) {
-    throw error;
+    serverReject(error);
   } else {
-    const address = `http://${program.host || 'localhost'}:${program.port}/`;
-    logger.info(`Storybook started on => ${chalk.cyan(address)}\n`);
+    serverResolve();
   }
 });
+
+Promise.all([webpackValid, serverListening])
+  .then(() => {
+    const address = `http://${program.host || 'localhost'}:${program.port}/`;
+    logger.info(`Storybook started on => ${chalk.cyan(address)}\n`);
+  })
+  .catch(error => logger.error(error));
diff --git a/app/react/src/server/middleware.js b/app/react/src/server/middleware.js
index e2ca8d2ace87..112740698259 100644
--- a/app/react/src/server/middleware.js
+++ b/app/react/src/server/middleware.js
@@ -8,6 +8,13 @@ import getIndexHtml from './index.html';
 import getIframeHtml from './iframe.html';
 import { getHeadHtml, getMiddleware } from './utils';
 
+let webpackResolve = () => {};
+let webpackReject = () => {};
+export const webpackValid = new Promise((resolve, reject) => {
+  webpackResolve = resolve;
+  webpackReject = reject;
+});
+
 export default function(configDir) {
   // Build the webpack configuration using the `getBaseConfig`
   // custom `.babelrc` file and `webpack.config.js` files
@@ -29,19 +36,33 @@ export default function(configDir) {
   };
 
   const router = new Router();
-  router.use(webpackDevMiddleware(compiler, devMiddlewareOptions));
+  const webpackDevMiddlewareInstance = webpackDevMiddleware(compiler, devMiddlewareOptions);
+  router.use(webpackDevMiddlewareInstance);
   router.use(webpackHotMiddleware(compiler));
 
   // custom middleware
   middlewareFn(router);
 
-  router.get('/', (req, res) => {
-    res.send(getIndexHtml({ publicPath }));
-  });
+  webpackDevMiddlewareInstance.waitUntilValid(stats => {
+    const data = {
+      publicPath: config.output.publicPath,
+      assets: stats.toJson().assetsByChunkName,
+    };
+
+    router.get('/', (req, res) => {
+      res.send(getIndexHtml({ publicPath }));
+    });
+
+    router.get('/iframe.html', (req, res) => {
+      const headHtml = getHeadHtml(configDir);
+      res.send(getIframeHtml({ ...data, headHtml, publicPath }));
+    });
 
-  router.get('/iframe.html', (req, res) => {
-    const headHtml = getHeadHtml(configDir);
-    res.send(getIframeHtml({ headHtml, publicPath }));
+    if (stats.toJson().errors.length) {
+      webpackReject(stats);
+    } else {
+      webpackResolve(stats);
+    }
   });
 
   return router;
diff --git a/examples/cra-storybook/package.json b/examples/cra-storybook/package.json
index 3cd54c700771..29ba51e8cbf3 100644
--- a/examples/cra-storybook/package.json
+++ b/examples/cra-storybook/package.json
@@ -19,11 +19,11 @@
     "uuid": "^3.0.1"
   },
   "devDependencies": {
-    "@storybook/addon-actions": "3.0.0",
-    "@storybook/addon-links": "3.0.0",
-    "@storybook/addon-events": "3.0.1",
-    "@storybook/addons": "3.0.0",
-    "@storybook/react": "3.0.0",
+    "@storybook/addon-actions": "^3.0.0",
+    "@storybook/addon-links": "^3.0.0",
+    "@storybook/addon-events": "^3.0.0",
+    "@storybook/addons": "^3.0.0",
+    "@storybook/react": "^3.0.0",
     "react-scripts": "1.0.1"
   },
   "private": true