diff --git a/.rubocop.yml b/.rubocop.yml
index 0ca77c83f..226e15662 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1,6 +1,6 @@
 require: rubocop-performance
 AllCops:
-  TargetRubyVersion: 2.2
+  TargetRubyVersion: 2.4
   # RuboCop has a bunch of cops enabled by default. This setting tells RuboCop
   # to ignore them, so only the ones explicitly set in this file are enabled.
   DisabledByDefault: true
diff --git a/lib/install/config/.browserslistrc b/lib/install/config/.browserslistrc
deleted file mode 100644
index e94f8140c..000000000
--- a/lib/install/config/.browserslistrc
+++ /dev/null
@@ -1 +0,0 @@
-defaults
diff --git a/lib/install/react.rb b/lib/install/react.rb
index c08e39717..5c0c6e9ff 100644
--- a/lib/install/react.rb
+++ b/lib/install/react.rb
@@ -1,10 +1,12 @@
 require "webpacker/configuration"
-require "fileutils"
+require "json"
 
-replace_babel_config = FileUtils.compare_file(Rails.root.join("babel.config.js"), "#{__dir__}/config/babel.config.js")
-
-say "Copying babel.config.js to app root directory"
-copy_file "#{__dir__}/examples/react/babel.config.js", "babel.config.js", force: replace_babel_config
+say "Adding react-preset to babel configuration in package.json"
+old_package = JSON.parse(File.read("package.json"))
+old_package["babel"] = {
+  "presets": ["./node_modules/@rails/webpacker/package/babel/preset-react.js"]
+}
+File.write("package.json", JSON.dump(old_package))
 
 say "Copying react example entry file to #{Webpacker.config.source_entry_path}"
 copy_file "#{__dir__}/examples/react/hello_react.jsx", "#{Webpacker.config.source_entry_path}/hello_react.jsx"
diff --git a/lib/install/template.rb b/lib/install/template.rb
index 96814fe27..f079f4e05 100644
--- a/lib/install/template.rb
+++ b/lib/install/template.rb
@@ -7,12 +7,6 @@
 say "Copying postcss.config.js to app root directory"
 copy_file "#{__dir__}/config/postcss.config.js", "postcss.config.js"
 
-say "Copying babel.config.js to app root directory"
-copy_file "#{__dir__}/config/babel.config.js", "babel.config.js"
-
-say "Copying .browserslistrc to app root directory"
-copy_file "#{__dir__}/config/.browserslistrc", ".browserslistrc"
-
 if Dir.exists?(Webpacker.config.source_path)
   say "The JavaScript app source directory already exists"
 else
@@ -45,6 +39,18 @@
 say "Installing dev server for live reloading"
 run "yarn add --dev webpack-dev-server"
 
+insert_into_file Rails.root.join("package.json").to_s, before: /\n}\n*$/ do
+  <<~JSON.chomp
+  ,
+    "babel": {
+      "presets": ["./node_modules/@rails/webpacker/package/babel/preset.js"]
+    },
+    "browserslist": [
+      "defaults"
+    ]
+  JSON
+end
+
 if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR > 1
   say "You need to allow webpack-dev-server host as allowed origin for connect-src.", :yellow
   say "This can be done in Rails 5.2+ for development environment in the CSP initializer", :yellow
diff --git a/lib/install/examples/react/babel.config.js b/package/babel/preset-react.js
similarity index 69%
rename from lib/install/examples/react/babel.config.js
rename to package/babel/preset-react.js
index a6c48efee..bb5960feb 100644
--- a/lib/install/examples/react/babel.config.js
+++ b/package/babel/preset-react.js
@@ -1,17 +1,13 @@
-module.exports = function(api) {
-  var validEnv = ['development', 'test', 'production']
-  var currentEnv = api.env()
-  var isDevelopmentEnv = api.env('development')
-  var isProductionEnv = api.env('production')
-  var isTestEnv = api.env('test')
+module.exports = function config(api) {
+  const validEnv = ['development', 'test', 'production']
+  const currentEnv = api.env()
+  const isDevelopmentEnv = api.env('development')
+  const isProductionEnv = api.env('production')
+  const isTestEnv = api.env('test')
 
   if (!validEnv.includes(currentEnv)) {
     throw new Error(
-      'Please specify a valid `NODE_ENV` or ' +
-        '`BABEL_ENV` environment variables. Valid values are "development", ' +
-        '"test", and "production". Instead, received: ' +
-        JSON.stringify(currentEnv) +
-        '.'
+      `Please specify a valid NODE_ENV or BABEL_ENV environment variable. Valid values are "development", "test", and "production". Instead, received: "${JSON.stringify(currentEnv)}".`
     )
   }
 
@@ -24,8 +20,7 @@ module.exports = function(api) {
             node: 'current'
           },
           modules: 'commonjs'
-        },
-        '@babel/preset-react'
+        }
       ],
       (isProductionEnv || isDevelopmentEnv) && [
         '@babel/preset-env',
diff --git a/lib/install/config/babel.config.js b/package/babel/preset.js
similarity index 63%
rename from lib/install/config/babel.config.js
rename to package/babel/preset.js
index bade1e33f..8311d591d 100644
--- a/lib/install/config/babel.config.js
+++ b/package/babel/preset.js
@@ -1,17 +1,13 @@
-module.exports = function(api) {
-  var validEnv = ['development', 'test', 'production']
-  var currentEnv = api.env()
-  var isDevelopmentEnv = api.env('development')
-  var isProductionEnv = api.env('production')
-  var isTestEnv = api.env('test')
+module.exports = function config(api) {
+  const validEnv = ['development', 'test', 'production']
+  const currentEnv = api.env()
+  const isDevelopmentEnv = api.env('development')
+  const isProductionEnv = api.env('production')
+  const isTestEnv = api.env('test')
 
   if (!validEnv.includes(currentEnv)) {
     throw new Error(
-      'Please specify a valid `NODE_ENV` or ' +
-        '`BABEL_ENV` environment variables. Valid values are "development", ' +
-        '"test", and "production". Instead, received: ' +
-        JSON.stringify(currentEnv) +
-        '.'
+      `Please specify a valid NODE_ENV or BABEL_ENV environment variable. Valid values are "development", "test", and "production". Instead, received: "${JSON.stringify(currentEnv)}".`
     )
   }