Why your ASP.NET Core views are not updating at runtime

If you have experience with ASP.NET but have only recently started building web applications with ASP.NET Core, you may have noticed that some of the features you are used to having during development, appear to be missing.

One of the first things you are likely to notice when you start off with a new ASP.NET Core project is that changes to static content such as HTML and CSS files are not reflected in the browser if you refresh the browser while your application is running or debugging.

In this article, I explain why this is and how you can address it.

Efficiency & Performance

One of the key benefits of ASP.NET Core compared to traditional ASP.NET applications is its focus on efficiency and raw performance.

The ASP.NET Core framework has been carefully engineered with “performance as a feature” from the start and it is currently one of the top-performing platforms for hosting web applications.

One of the ways ASP.NET Core achieves great performance is by keeping things as lightweight and modular as possible. This means that the overall size of your application will typically be much smaller and there will, therefore, be less for the web server to load.

Older ASP.NET projects have a lot of baggage to carry around, partly due to the age of the framework as it has gotten bigger over time and the integrated pipeline which coupled it to IIS until Kestrel came along. ASP.NET relies on the System.Web assembly which is bloated with many different features that you may never need to use which is wasteful.

An ASP.NET Core project, on the other hand, starts off with the bare minimum and any additional features that you need are typically added by installing NuGet packages.

Runtime Compilation

Razor views, which are used in both Razor Pages and MVC projects in ASP.NET Core, are compiled by default whenever you build or publish your project.

Runtime Compilation is a feature that enables views to be recompiled at runtime if a change is made to a view file while your application is running.

The Runtime Compilation of views is a feature that isn’t included in an ASP.NET Core project by default.

Package Setup

In order to get access to the Runtime Compilation feature, you’ll need to install the Runtime Compilation NuGet package into your project.

After installing the package, a few changes need to be made to your project in order to enable the Runtime Compilation.

First of all, in the spirit of keeping things efficient, you’ll want to update your project file such that Runtime Compilation is not included in production. You’ll typically only need this feature when you are developing so it makes sense to exclude it when your application is released.

To do this, open up your project file and update the appropriate PackageReference element with a Condition attribute as shown below.

<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.1.6" Condition="'$(Configuration)' == 'Debug'" />

Note that the value of your Version attribute may differ from the example shown above.

The Condition stipulates that the package should only be included in the project if the Solution Configuration is set to ‘Debug’ mode.

This will help to keep the application as small as possible whenever it is deployed.

Code Configuration

Now that the NuGet package is installed, we need to do some configuration in the code.

In theConfigureServices method of yourStartup class, you’ll need to add a call to the AddRazorRuntimeCompilation extension method which is defined within the ‘RuntimeCompilation’ assembly.

Before doing this, add a property to your Startup class and add a parameter to the constructor, in order to capture the IWebHostEnvironment, as shown in the code sample below.

public IWebHostEnvironment Env { get; }
public Startup(IWebHostEnvironment env)
    Env = env;

The above code will allow the properties/methods of the IWebHostEnvironment to be inspected/called within the ConfigureServices method.

Now update your ConfigureServices method to call the AddRazorRuntimeCompilation extension method, as per the code sample below.

public void ConfigureServices(IServiceCollection services)
    var mvcBuilder = services.AddControllersWithViews();
    #if DEBUG
    if (Env.IsDevelopment())

In the above code, we are only adding support for Runtime Compilation if the DEBUG symbol is defined and if development mode is enabled.

Now if you run your application in Debug mode any changes made to your views while running will be reflected within the browser whenever you refresh.

Browser Link

Another package that you may wish to install to help with the speed of view development is the Browser Link NuGet package.

The package is described by Microsoft as follows.

A middleware that supports creating a communication channel between the development environment and one or more web browsers.

Essentially it allows your application to be connected to one or more web browsers and for all of the connected browsers to be refreshed at the same time after making a view change directly from your development environment e.g. from Visual Studio.

This can be very useful whenever you want to test changes to your application in multiple browsers at the same time.

It can also be useful when you are working on a complex view and you want to see the changes reflected immediately on save without having to refresh the browser.

Package Setup

In order to get access to the Browser Link feature, you will need to install the Browser Link NuGet package into your project.

After installing the package, there are a few small changes to make again to your project.

Note that Runtime Compilation needs to be set up before the Browser Link feature will work correctly.

As per the Runtime Compilation package example, we can conditionally reference the Browser Link package so that it does not get deployed to production.

Open up your project file and then update the appropriate PackageReference element with a Condition attribute, as shown below.

<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.2.0" Condition="'$(Configuration)' == 'Debug'" />

Note that the value of your Version attribute may differ from the example shown above.

As per the Runtime Compilation package example, the Condition stipulates that the package should only be included in the project if the Solution Configuration is set to ‘Debug’ mode.

Code Configuration

Unlike Runtime Compilation, the Browser Link needs to be configured within the Configure method of your Startup class.

Update your Configure method as follows with a call to the UseBrowserLink extension method.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    if (env.IsDevelopment())


    }     // ... Remainder of the Configure method omitted for brevity. }

Now if you start your application without debugging (Ctrl + F5 in Visual Studio) and leave the Solution Configuration in ‘Debug’ mode, you will be able to refresh all connected browsers directly from your development environment.

The Browser Link refresh button can be seen at the top-right of the screenshot from Visual Studio below.

Browser Link icon in Visual Studio
Browser Link icon in Visual Studio

You can connect as many browsers as you need while you are developing and press the blue refresh button whenever you want to see the changes you have made reflected in the browser.


In this article, we’ve seen how we can add the ability to have our views updated at runtime using the appropriate NuGet packages and we have looked at how to refresh both via the browser and directly from the development environment.

At the same time, I’ve covered the best practices for conditionally excluding NuGet packages and code references for when our application goes into production, in order to keep our web applications as lightweight as possible.

I hope this article helps to get you up and running quickly with the Runtime Compilation and Browser Link features in ASP.NET Core and speeds up your view development time.

If you have any questions please leave a comment and I will do my best to help.

I hope you enjoyed this post! Comments are always welcome and I respond to all questions.

If you like my content and it helped you out, please check out the button below 🙂