Skip to content
Home » What Happened to ASP.NET Core JavaScript Services — and What to Use Instead

What Happened to ASP.NET Core JavaScript Services — and What to Use Instead

ASP.NET Core JavaScript Services no longer exists. Microsoft marked Microsoft.AspNetCore.SpaServices and Microsoft.AspNetCore.NodeServices obsolete in ASP.NET Core 3.0 and removed them in .NET 5. The official replacement is Microsoft.AspNetCore.SpaServices.Extensions combined with your SPA framework’s own CLI — and in the current project templates, even that has largely given way to the development-time SPA proxy.

If you arrived here from a link written between 2017 and 2019, you were probably looking for a tutorial on UseWebpackDevMiddleware, UseAngularCliServer, or server-side prerendering with aspnet-prerendering. None of that works on a supported .NET version any more. This page explains what happened, what replaced it, and what a migration actually involves — because the official announcement is short and leaves out the parts that cost you an afternoon.

What was ASP.NET Core JavaScript Services?

JavaScript Services was Microsoft’s first serious attempt to make ASP.NET Core and Node-based frontends work as one project. It shipped as two NuGet packages plus a family of npm modules, and it did something unusual for a .NET library: it started a Node process from inside your ASP.NET Core application and talked to it over a socket.

That gave you three things that were genuinely hard to get in 2017. Webpack ran inside the ASP.NET Core dev server through UseWebpackDevMiddleware, so a single dotnet run started both halves of the stack. Server-side prerendering through aspnet-prerendering executed your Angular or React app in Node on the server and sent finished HTML to the browser. And NodeServices let you call arbitrary JavaScript from C# — image processing, PDF generation, anything with a good npm package and no .NET equivalent.

The full list of what was retired: the NuGet packages Microsoft.AspNetCore.SpaServices and Microsoft.AspNetCore.NodeServices, and the npm modules aspnet-angular, aspnet-prerendering, aspnet-webpack, aspnet-webpack-react and domain-task.

Why did Microsoft obsolete it?

The stated reason is that the packages stopped being necessary. When JavaScript Services was designed, the SPA frameworks had no standard tooling of their own worth integrating with. By the time ASP.NET Core 2.1 shipped in May 2018, Angular CLI and create-react-app had become the normal way to build a frontend, and both were better at it than a wrapper written in C#.

So Microsoft replaced deep integration with a thinner one. Instead of hosting webpack inside .NET, ASP.NET Core would simply start the framework’s own dev server and proxy to it. That is the entire idea behind SpaServices.Extensions, and it explains why the migration is mostly a matter of deleting code rather than rewriting it.

The announcement went out in August 2019, the packages were marked obsolete in ASP.NET Core 3.0, and removal followed in .NET 5. If you are still on a runtime where these packages load, you are on a version that stopped receiving security fixes years ago — which is the more urgent problem.

What should I use instead in 2026?

For a new project, use the first-party templates. Visual Studio and the .NET CLI ship prewired ASP.NET Core solutions for Angular and for React with Vite, and both arrive with proxy configuration, launch profiles and HTTPS already set up. You get two projects in one solution, and both start together.

The mechanism underneath is the SPA proxy: a middleware that is active only in development. It intercepts an incoming request, checks whether the frontend dev server is already running, and either forwards to it or starts a new instance. Your production build is unaffected — there, the frontend is a folder of static files and the proxy does not exist.

# Angular
dotnet new angular -o MyApp

# React with Vite
dotnet new react -o MyApp

If you want the cleanest development setup, skip the .NET-side proxy entirely and use your framework’s own. Angular’s proxy.conf.json forwards API calls from the Angular dev server to the ASP.NET Core backend, which avoids CORS without any middleware at all. Vite does the same through server.proxy. Both are fewer moving parts than anything ASP.NET Core offers.

How do I migrate an existing JavaScript Services project?

Start by deleting rather than replacing. Most JavaScript Services code has no successor because the problem it solved no longer exists — the frontend toolchain handles it.

Remove the obsolete packages and the npm modules:

dotnet remove package Microsoft.AspNetCore.SpaServices
dotnet remove package Microsoft.AspNetCore.NodeServices
npm uninstall aspnet-webpack aspnet-webpack-react aspnet-prerendering aspnet-angular domain-task

Then strip the middleware. In Startup.cs or Program.cs, calls like app.UseWebpackDevMiddleware(...) and any asp-prerender-module tag helpers in your views come out entirely. There is nothing to put in their place — the dev server does that job now.

Add the replacement package and point it at your frontend:

dotnet add package Microsoft.AspNetCore.SpaServices.Extensions
app.UseSpa(spa =>
{
    spa.Options.SourcePath = "ClientApp";

    if (app.Environment.IsDevelopment())
    {
        spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
    }
});

Note the shape of that code: it proxies to a dev server you start yourself, rather than starting one for you. UseAngularCliServer and UseReactDevelopmentServer exist and will launch the CLI, but they add a startup delay on every dotnet run and swallow the frontend’s console output. Running ng serve in a second terminal is less clever and considerably more pleasant.

What happened to server-side prerendering and hot module reload?

Both moved out of ASP.NET Core, and Microsoft’s answer is to consult the SPA framework’s documentation. That is a shorter answer than the situation deserves, so here is the practical version.

Hot module reload is now a solved problem on the frontend side. Vite’s HMR is close to instant and needs no configuration; the Angular dev server has had it for years. You lose nothing here — the replacement is strictly better than what UseWebpackDevMiddleware offered.

Server-side rendering is the real loss, and it is worth being honest about it. There is no drop-in successor inside ASP.NET Core. If you need SSR, you run it where the framework supports it: Angular SSR with its own Node server, or Next.js and Remix on the React side. Your ASP.NET Core application then becomes an API behind that Node process rather than the thing serving HTML. That is a bigger architectural change than the rest of this migration combined, and it is the reason some JavaScript Services projects never moved.

If your only use of NodeServices was calling JavaScript from C#, the community package Jering.Javascript.NodeJS covers that case and is actively maintained.

Do I still need SpaServices.Extensions at all?

Often not. The package earns its place in exactly one situation: you want a single dotnet run to bring up the whole stack, and you are willing to pay for it with a slower startup and a merged console.

For everything else there are simpler paths. In development, the frontend’s own proxy is fewer parts. In production, your built frontend is a directory of static assets — app.UseStaticFiles() and a fallback route to index.html do the entire job:

app.MapFallbackToFile("index.html");

That single line replaces most of what people still install SpaServices.Extensions for. Worth checking before you add a dependency to a project that may not need one.

The short version

JavaScript Services solved a real problem in 2017 and was made redundant by the frontend ecosystem growing up. If you are maintaining a project that still uses it, you are on an unsupported runtime and the migration is mostly deletion. If you are starting something new, use the current templates and let each side of the stack do what it is good at.

Leave a Reply

Your email address will not be published. Required fields are marked *

Ein Webprojekt von DeOlivera Webprojekte