How to integrate ReactJS in existing MVC app

React is a great front-end library where the concepts are easy to grasp such as state and components, but it can be confusing, a little bit difficult to integrate without the use of boilerplate like create-react-app.

According to the official page, React serves as a “V” in MVC. I’ve been trying to scratch my head for years before I got the concept and how can I integrate it gracefully in my existing MVC app.

A lot (or some) of you may be wondering about how we can integrate ReactJS into MVC app for the longest time. I actually wondered about that myself as well since my tech stack revolves around .net ecosystem until I learned how to make use and integrate it the hard way.

Like you, I digged deeper into the rabbit hole till I found the answer by learning the front-end ecosystems surrounding React, etc.

Having found the solution, let us answer how we can integrate ReactJS in our existing MVC app:

Ways to integrate ReactJS in MVC

As some of you might have know already, there are a couple of ways we can integrate ReactJS in our existing MVC projects. Here they are:

Importing the React script

This is by far the easiest approach among the three, but you won’t be able to utilize JSX syntax with this method. You’re going to use plain javascript methods to construct your own React components.

So it’s up to you to use this method or not. You can find the cdn links here to get started with React right away.

Using is a .net library that allows you to make use of JSX syntax on the fly by installing it via nuget package. You can find it here.

Using Webpack and Babel

Last but not the least is integrating through the use of webpack and babel.

This is by far is my favorite method of integrating the front-end library to our existing MVC app as it’s flexible, customizable, and we can tune the performance of React at will through the use of webpack.

Personally, I prefer this method over the two. Here’s why:

  • Have better controls on the juicy stuffs of javascript ecosystem – Things like ES8, dynamically import ES modules, new React syntax definitions, etc. I feel like I’m missing a lot in javascript ecosystem without having to know how to make use of webpack. And since you can customize everything yourself, you can have the latest features of ECMAScript as you like at your fingertips.
  • Customizable scripts – Allows you to customize how webpack should compile/transpile React source code efficiently with less bloatware.
  • Better Separation of Concerns for React components and MVC – What I appreciate most in using webpack and babel is the fact that I have better controls on how can I separate React components from MVC structure of Although you might be able to achieve this using as I haven’t used it.
  • Improve script performance – One of my favorite things about webpack is its ability to optimize and improve the performance of the script bundle. React just simply gets attached to the DOM once loaded, so you could imagine how expensive this operation is since it loads all components and scripts associated with that React DOM. And that’s where the script performance optimization of webpack comes into play.
  • Improve your knowledge in javascript ecosystem – This is by far the main reason why I learned webpack and babel down to my core is also because to strengthen my knowledge in javascript ecosystem. This allows me to grasp the front-end side of things and improve the loading speed.

We are going to use this method for the most part. If you have no knowledge in webpack and babel, don’t worry. We won’t delve deeper into these tools but just scratch the surface enough for you to understand the basics and integrate React into MVC projects with less hassle.

What can I expect in this tutorial?

What you’ll expect in this tutorial is a straightforward, direct approach of integrating React using Webpack and Babel. What this tutorial doesn’t do is give you bunch of definition about what webpack and babel is.

If you’re looking for their definition and in-depth implementations, look elsewhere. If you don’t have any prior knowledge of these tools, don’t worry. I will make it as less complicated to implement as possible.

So, let’s get the hacking started!

Integrating ReactJS using Webpack and Babel

We are now going to delve deeper on implementing React using Webpack and Babel. Let’s get started!

Check your existing MVC project MVC template

Check what version of MVC are you using. Is it 4? 5?

Either way, it doesn’t matter. What matters to us is the “Scripts” folder. If there’s nothing in the project, create one so that it follows the structure of our tutorial.

Initialize package.json file

We need to initialize the package.json file if we were to make use of webpack since we’re going to use npm to download and use the package later on.

To do that, go to command prompt and type this command:

npm init -y

This will initialize package.json file for you. And after typing that command you will see something like so:

Now you will have package.json in the project and you can now start installing npm packages.

Install npm packages

Now we need to download the webpack using npm commands since we now have package.json file. To do so, type this command:

npm install webpack webpack-cli --save-dev

We include --save-dev parameters to tell npm that this package file should be saved in package.json in any case other developers will download the repository for development use and install all packages in their local machine using npm install.

Now let’s also install react-related packages:

npm install react react-dom --save-dev

These packages allow you to use react components at your script.

Lastly, we need to install the following scripts related to babel:

npm install @babel/core @babel/preset-react babel-loader --save-dev

This allows us to make use of babel to transpile our react components. More into that later.

Creating root script for ReactDOM

We need to create a script for all your components to load in root element. So create a src folder under Scripts folder and create new script file named index.js under src folder then paste the following code:

import React from 'react';
import ReactDOM from 'react-dom';

const App = () => <div>Hello world!</div>;

ReactDOM.render(<App />, document.getElementById("root"));

We are going to use this script later on when we setup our webpack config file.

Setting up webpack config file

Once all the npm packages we need were done installing, next is we need to setup webpack configuration file. Although, webpack claims zero configuration on our part, it’s still better to configure it ourselves to have better control over the script and its performance for bundling. To know more about webpack, go over here.

To start, create a folder named config and add webpack.config.js file into Scripts folder and paste this source code:

const path = require("path");

module.exports = {
    entry: {
        index: "./Scripts/src/index.js"
    output: {
        path: path.resolve(__dirname, "../dist"),
        filename: "[name].js"
    module: {
        rules: [
                use: {
                    loader: "babel-loader"
                test: /\.js$/,
                exclude: /node_modules/ //excludes node_modules folder from being transpiled by babel. We do this because it's a waste of resources to do so.

Let us explain the following details:

Entry – The starting point of your script. This is where you usually put all the starting scripts that initiate ReactDOM and its components to load (usually index.js). You can have multiple entries as you like.

Output – This is where you put the output files that was generated as a result of your script in entry point.

  • Path – this is the path that determines the output folder. In this parameter, we put “dist” as our folder where we put our output files for later use
  • Filename – This is the filename of your output. If you have two or more entry, you need to use a variable as its filename to reflect it from its entry point name. In this case, we used “[name]” as a variable for substitution. Learn about multiple entry points here.

Module – This is where you determine how the different types of modules will be treated. We will make use of “babel-loader” module to transpile React components in this part. Learn more about module here.

Setting up babel

Babel’s role in webpack ecosystem is to transpile various ECMAScript versions and React. It serves as a transpiler/compiler for webpack. Learn more about babel here.

Create .babelrc file in root folder and paste this:

    "presets": [
    "plugins": [

What’s happening here is we are telling babel to use react presets so that we can transpile React. To know more on react presets in babel and you want it to configure further, look over here.

It’s that simple.

Building React scripts using Webpack

We are now ready to build react using webpack so we can make use of it in our View page.

To start building, run this in your command prompt:

webpack --config=Scripts/config/webpack.config.js

This will start creating a dist folder and build files which we will need for our View page.

Transferring webpack command to package.json

Instead of typing this whole command:

webpack --config=Scripts/config/webpack.config.js

We can go over and transfer this onto package.json file for ease of use.

Open your package.json file and paste this under scripts object:

"build": "webpack --config=Scripts/config/webpack.config.js"

This allows us to reuse the command without typing the whole command.

Now back to command prompt and type this:

npm run build

This does the same thing as our webpack command as we put it as shortcut in our package.json configuration file.

Importing the build file in View page

Since we can’t import React JSX directly in the view page, we still need the help of webpack and babel to do those stuffs for us.

So, after we run the command above, you should see the dist folder inside the Scripts folder on where we tell our webpack config to save the output files in Scripts/dist folder.

It should look like this in your project:

Include this folder in your project and let’s import index.js in our View page. Then paste this code inside your Home/Index.cshtml page:

<div id="root"></div>


Then your page will look something like this now:


We now have a basic gist of using React in existing MVC projects and make use of the power of both webpack and babel in our projects. Let me know your thoughts or when you get into trouble in following the tutorial!

A Software Engineer who loves to code and write articles.

15 comments On How to integrate ReactJS in existing MVC app

  • Great tutorial, thanks! I’ve spent a week or so off and on trying to integrate React into an existing MVC .NET Framework app, and this took me right through the steps and worked first time!
    One minor nit: adding “npm run build” as a pre-build event command line in VS completes the build automation.

    • Hey Steven. Thank you for appreciating my post! I haven’t seen any MVC tutorials that teach us how to integrate React in it so I decided that I will write one. I will also publish my post soon about architecting React in MVC if you’re interested.

      For your minor suggestion, I’ll look into it.

  • Need help here. I get a blank screen. It is probably not able to find the id=root. I followed the exact procedure you mentioned in this article.

  • I got the mistake.
    C:\Users\Dima\source\repos\WebApplication5\WebApplication5>webpack –config=webp
    Hash: c1e997668e471a8e01a4
    Version: webpack 4.41.2
    Time: 112ms
    Built at: 2019-10-31 15:12:23
    1 asset
    Entrypoint index = index.js
    [0] ./Scripts/src/index.js 5.9 KiB {0} [built] [failed] [1 error]

    WARNING in configuration
    The ‘mode’ option has not been set, webpack will fallback to ‘production’ for th
    is value. Set ‘mode’ option to ‘development’ or ‘production’ to enable defaults
    for each environment.
    You can also set it to ‘none’ to disable any default behavior. Learn more: https

    ERROR in ./Scripts/src/index.js
    Module build failed (from ./node_modules/babel-loader/lib/index.js):
    SyntaxError: C:\Users\Dima\source\repos\WebApplication5\WebApplication5\Scripts\
    src\index.js: Unexpected token (4:18)

    2 | import ReactDOM from ‘react-dom’;
    3 |
    > 4 | const App = () => Hello world!;
    | ^
    5 |
    6 | ReactDOM.render(, document.getElementById(“root”));
    at Parser.raise (C:\Users\Dima\source\repos\WebApplication5\WebApplication5\
    at Parser.unexpected (C:\Users\Dima\source\repos\WebApplication5\WebApplicat
    at Parser.parseExprAtom (C:\Users\Dima\source\repos\WebApplication5\WebAppli
    at Parser.parseExprSubscripts (C:\Users\Dima\source\repos\WebApplication5\We
    at Parser.parseMaybeUnary (C:\Users\Dima\source\repos\WebApplication5\WebApp
    at Parser.parseExprOps (C:\Users\Dima\source\repos\WebApplication5\WebApplic
    at Parser.parseMaybeConditional (C:\Users\Dima\source\repos\WebApplication5\
    at Parser.parseMaybeAssign (C:\Users\Dima\source\repos\WebApplication5\WebAp
    at Parser.parseFunctionBody (C:\Users\Dima\source\repos\WebApplication5\WebA
    at Parser.parseArrowExpression (C:\Users\Dima\source\repos\WebApplication5\W
    at Parser.parseParenAndDistinguishExpression (C:\Users\Dima\source\repos\Web
    at Parser.parseExprAtom (C:\Users\Dima\source\repos\WebApplication5\WebAppli
    at Parser.parseExprSubscripts (C:\Users\Dima\source\repos\WebApplication5\We
    at Parser.parseMaybeUnary (C:\Users\Dima\source\repos\WebApplication5\WebApp
    at Parser.parseExprOps (C:\Users\Dima\source\repos\WebApplication5\WebApplic
    at Parser.parseMaybeConditional (C:\Users\Dima\source\repos\WebApplication5\
    at Parser.parseMaybeAssign (C:\Users\Dima\source\repos\WebApplication5\WebAp
    at Parser.parseVar (C:\Users\Dima\source\repos\WebApplication5\WebApplicatio
    at Parser.parseVarStatement (C:\Users\Dima\source\repos\WebApplication5\WebA
    at Parser.parseStatementContent (C:\Users\Dima\source\repos\WebApplication5\
    at Parser.parseStatement (C:\Users\Dima\source\repos\WebApplication5\WebAppl
    at Parser.parseBlockOrModuleBlockBody (C:\Users\Dima\source\repos\WebApplica
    at Parser.parseBlockBody (C:\Users\Dima\source\repos\WebApplication5\WebAppl
    at Parser.parseTopLevel (C:\Users\Dima\source\repos\WebApplication5\WebAppli
    at Parser.parse (C:\Users\Dima\source\repos\WebApplication5\WebApplication5\
    at parse (C:\Users\Dima\source\repos\WebApplication5\WebApplication5\node_mo
    at parser (C:\Users\Dima\source\repos\WebApplication5\WebApplication5\node_m
    at normalizeFile (C:\Users\Dima\source\repos\WebApplication5\WebApplication5
    at runSync (C:\Users\Dima\source\repos\WebApplication5\WebApplication5\node_
    at runAsync (C:\Users\Dima\source\repos\WebApplication5\WebApplication5\node
    at C:\Users\Dima\source\repos\WebApplication5\WebApplication5\node_modules\@
    at processTicksAndRejections (internal/process/task_queues.js:75:11)

  • I want the react client and I want the model and controller as my back end. Do I need separate port for running react and server ? If yes how should I configure separate port for react client and mvc backend.

    • Hi Nupur,

      That depends on your use-case. You could use separate ports/domains for separating back-end from front-end via RESTful services, or just put it in one project. Although one concern you’re going to deal with if you decide to separate the projects I think is CORS which could be painful to resolve.

  • Hi Sonny, Appreciated for your efforts & time for the complete instruction! I tried 2 different ones and no luck from there but yours are clear & simple. Great Job!

  • Hi Sonny. Thanks for your time. The instructions worked well until the last one.
    I created a new .Net Core MVC project and then applied your instruction to it.
    When I added @Scripts.Render(“~/Scripts/dist/index.js”) into the cshtml file, it gave me the error of CS0103 The name ‘Scripts’ does not exist in the current context.
    I added @using System.Web.Optimization at the top of the cshtml file and my error changes to Error CS7069 Reference to type ‘IHtmlString’ claims it is defined in ‘System.Web’, but it could not be found. The error is still on the line of @Scripts.Render
    Any ideas what I am missing?

    • Hi Jeff,

      I haven’t used .net Core MVC personally. But I think you may probably need to import the scripts the way .net core requires you to. What’s important is you import the script into the page so that you run React script properly into your .net core project.

  • Hi, thank you very much for the tutorial, I have been trying to make it work, but when I try the webpack installation I get the following error: “The term webpack is not recognized as a cmdlet, function, script file or executable program. So i Open my package.json file and paste under scripts object the following code: “build”: “webpack –config=Scripts/config/webpack.config.js”.
    When i type this: npm run build, i get this:

    > AspNetReactIntegration@1.0.0 build C:\Users\NtbkLap\source\repos\AspNetReactIntegration
    > webpack –config=Scripts/config/webpack.config.js

    (function (exports, require, module, __filename, __dirname) { onst path = require(“path”);

    SyntaxError: Unexpected identifier
    at new Script (vm.js:84:7)
    at NativeCompileCache._moduleCompile (C:\Users\NtbkLap\source\repos\AspNetReactIntegration\node_modules\v8-compile-cache\v8-compile-cache.js:240:18)
    at Module._compile (C:\Users\NtbkLap\source\repos\AspNetReactIntegration\node_modules\v8-compile-cache\v8-compile-cache.js:186:36)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1103:10)
    at Module.load (internal/modules/cjs/loader.js:914:32)
    at Function.Module._load (internal/modules/cjs/loader.js:822:14)
    at Module.require (internal/modules/cjs/loader.js:956:19)
    at require (C:\Users\NtbkLap\source\repos\AspNetReactIntegration\node_modules\v8-compile-cache\v8-compile-cache.js:161:20)
    at WEBPACK_OPTIONS (C:\Users\NtbkLap\source\repos\AspNetReactIntegration\node_modules\webpack-cli\bin\utils\convert-argv.js:114:13)
    at requireConfig (C:\Users\NtbkLap\source\repos\AspNetReactIntegration\node_modules\webpack-cli\bin\utils\convert-argv.js:116:6)
    at C:\Users\NtbkLap\source\repos\AspNetReactIntegration\node_modules\webpack-cli\bin\utils\convert-argv.js:123:17
    at Array.forEach ()
    at module.exports (C:\Users\NtbkLap\source\repos\AspNetReactIntegration\node_modules\webpack-cli\bin\utils\convert-argv.js:121:15)
    at C:\Users\NtbkLap\source\repos\AspNetReactIntegration\node_modules\webpack-cli\bin\cli.js:71:45
    at Object.parse (C:\Users\NtbkLap\source\repos\AspNetReactIntegration\node_modules\yargs\yargs.js:567:18)
    at C:\Users\NtbkLap\source\repos\AspNetReactIntegration\node_modules\webpack-cli\bin\cli.js:49:8
    at Object. (C:\Users\NtbkLap\source\repos\AspNetReactIntegration\node_modules\webpack-cli\bin\cli.js:366:3)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1103:10)
    at Module.load (internal/modules/cjs/loader.js:914:32)
    at Function.Module._load (internal/modules/cjs/loader.js:822:14)
    at Module.require (internal/modules/cjs/loader.js:956:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object. (C:\Users\NtbkLap\source\repos\AspNetReactIntegration\node_modules\webpack\bin\webpack.js:127:2)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1103:10)
    at Module.load (internal/modules/cjs/loader.js:914:32)
    at Function.Module._load (internal/modules/cjs/loader.js:822:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1143:12)
    at internal/main/run_main_module.js:16:11
    npm ERR! code ELIFECYCLE
    npm ERR! errno 1
    npm ERR! AspNetReactIntegration@1.0.0 build: `webpack –config=Scripts/config/webpack.config.js`
    npm ERR! Exit status 1
    npm ERR!
    npm ERR! Failed at the AspNetReactIntegration@1.0.0 build script.
    npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

    npm ERR! A complete log of this run can be found in:
    npm ERR! C:\Users\NtbkLap\AppData\Roaming\npm-cache\_logs\2019-11-22T19_56_07_003Z-debug.log.

    Can you helpme?
    Thanks a lot

Leave a reply:

Your email address will not be published.

Site Footer