diff --git a/Gemfile b/Gemfile
index f9aecca70ffd73ce46a9c52ff9f2338bd7f49584..6af69e8a37af14064a1b4f8f649816e763fd6745 100644
--- a/Gemfile
+++ b/Gemfile
@@ -312,6 +312,8 @@ group :development, :test do
   gem 'activerecord_sane_schema_dumper', '0.2'
 
   gem 'stackprof', '~> 0.2.10'
+
+  gem 'rack-proxy', '~> 0.6.0'
 end
 
 group :test do
diff --git a/Gemfile.lock b/Gemfile.lock
index 0434fdefcd57323c744b1883f07d3f76ed1735ef..bcf500b16f96ff563eadeaa05e2dd962f6810dd2 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -544,6 +544,8 @@ GEM
       rack (>= 1.1)
     rack-protection (1.5.3)
       rack
+    rack-proxy (0.6.0)
+      rack
     rack-test (0.6.3)
       rack (>= 1.0)
     rails (4.2.7.1)
@@ -943,6 +945,7 @@ DEPENDENCIES
   rack-attack (~> 4.4.1)
   rack-cors (~> 0.4.0)
   rack-oauth2 (~> 1.2.1)
+  rack-proxy (~> 0.6.0)
   rails (= 4.2.7.1)
   rails-deprecated_sanitizer (~> 1.0.3)
   rainbow (~> 2.1.0)
diff --git a/config/application.rb b/config/application.rb
index 4efe73c7798ea22ff243dad1ddd656c83d922290..9088d3c432b3fc8b9c01940a074a0db51606137d 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -84,6 +84,8 @@ module Gitlab
     config.webpack.config_file = "config/webpack.config.js"
     config.webpack.output_dir  = "public/assets/webpack"
     config.webpack.public_path = "assets/webpack"
+
+    # Webpack dev server configuration is handled in initializers/static_files.rb
     config.webpack.dev_server.enabled = false
 
     # Enable the asset pipeline
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 42e5f105d4659ba8814e3dd21784f18a210b0be0..2906633fcbcad0061d5cf948f92d40f2d266b404 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -505,6 +505,16 @@ production: &base
     # Git timeout to read a commit, in seconds
     timeout: 10
 
+  ## Webpack settings
+  # If enabled, this will tell rails to serve frontend assets from the webpack-dev-server running
+  # on a given port instead of serving directly from /assets/webpack. This is only indended for use
+  # in development.
+  webpack:
+    # dev_server:
+    #   enabled: true
+    #   host: localhost
+    #   port: 3808
+
   #
   # 5. Extra customization
   # ==========================
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 4f33aad8693af2617590816f85f0f12be10bd6e7..ea61aa9e047e421b896c864ec3e58d1cf63184a0 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -409,6 +409,15 @@ Settings.rack_attack.git_basic_auth['bantime'] ||= 1.hour
 Settings['gitaly'] ||= Settingslogic.new({})
 Settings.gitaly['socket_path'] ||= ENV['GITALY_SOCKET_PATH']
 
+#
+# Webpack settings
+#
+Settings['webpack'] ||= Settingslogic.new({})
+Settings.webpack['dev_server'] ||= Settingslogic.new({})
+Settings.webpack.dev_server['enabled'] ||= false
+Settings.webpack.dev_server['host']    ||= 'localhost'
+Settings.webpack.dev_server['port']    ||= 3808
+
 #
 # Testing settings
 #
diff --git a/config/initializers/static_files.rb b/config/initializers/static_files.rb
index d6dbf8b9fbfca8d9edc43a8e09a650cd1a3c5904..718cdd517821d40457f0b30fd98bc519e2a037a7 100644
--- a/config/initializers/static_files.rb
+++ b/config/initializers/static_files.rb
@@ -12,4 +12,25 @@ if app.config.serve_static_files
     app.paths["public"].first, 
     app.config.static_cache_control
   )
+
+  # If webpack-dev-server is configured, proxy webpack's public directory
+  # instead of looking for static assets
+  if Gitlab.config.webpack.dev_server.enabled
+    app.config.webpack.dev_server.merge!(
+      enabled: true,
+      host: Gitlab.config.gitlab.host,
+      port: Gitlab.config.gitlab.port,
+      https: Gitlab.config.gitlab.https,
+      manifest_host: Gitlab.config.webpack.dev_server.host,
+      manifest_port: Gitlab.config.webpack.dev_server.port,
+    )
+
+    app.config.middleware.insert_before(
+      Gitlab::Middleware::Static,
+      Gitlab::Middleware::WebpackProxy,
+      proxy_path: app.config.webpack.public_path,
+      proxy_host: Gitlab.config.webpack.dev_server.host,
+      proxy_port: Gitlab.config.webpack.dev_server.port,
+    )
+  end
 end
diff --git a/lib/gitlab/middleware/webpack_proxy.rb b/lib/gitlab/middleware/webpack_proxy.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3fe32adeade7bcdc8282a1c7ebeea00be7c5d34e
--- /dev/null
+++ b/lib/gitlab/middleware/webpack_proxy.rb
@@ -0,0 +1,24 @@
+# This Rack middleware is intended to proxy the webpack assets directory to the
+# webpack-dev-server.  It is only intended for use in development.
+
+module Gitlab
+  module Middleware
+    class WebpackProxy < Rack::Proxy
+      def initialize(app = nil, opts = {})
+        @proxy_host = opts.fetch(:proxy_host, 'localhost')
+        @proxy_port = opts.fetch(:proxy_port, 3808)
+        @proxy_path = opts[:proxy_path] if opts[:proxy_path]
+        super(app, opts)
+      end
+
+      def perform_request(env)
+        unless @proxy_path && env['PATH_INFO'].start_with?("/#{@proxy_path}")
+          return @app.call(env)
+        end
+
+        env['HTTP_HOST'] = "#{@proxy_host}:#{@proxy_port}"
+        super(env)
+      end
+    end
+  end
+end