This article was originally published on our engineering blog, WithNext.NET. It's reposted here with the canonical link pointing back to the original.
You want React and TypeScript on the front end, but pulling a whole Node.js + npm + bundler toolchain into a .NET project feels heavy. That trade-off has been a quiet pain for a lot of ASP.NET Core developers. JsxCore, an about-to-ship library by UK developer David Whitney, rethinks it: it's a view engine that lets you write ASP.NET Core views in JSX/TSX and render them with React or Preact — and its headline feature is that it runs on the .NET SDK alone, with no Node.js required.
This post walks through what JsxCore solves, how you write it, and what it means for .NET teams, based on the project's GitHub repository.
🆕 Follow-up: JsxCore has since shipped 1.0.0, and its author is now bringing C# to Astro with a PoC called AstroSharp — read the follow-up.
What is JsxCore?
JsxCore aims to bring a "vite-like developer experience to the .NET ecosystem." You write your views as .tsx files and return them from a controller or a Minimal API. Each view can render on the server (for the first paint and SEO), in the browser (for interactivity), or both. TypeScript is transpiled automatically, and the browser resolves the module graph without a bundler. It's MIT-licensed and targets .NET 8, 9, and 10.
Both React and Preact are supported (Preact ships built-in; React via restoration). Because JsxCore registers as an ASP.NET Core IViewEngine, it also plays nicely with classic MVC and return View(). In other words, you get "the feel of React" and "the conventions of ASP.NET Core" in a single project.
Getting started
You add one NuGet package. No Node.js install — the .NET SDK is all you need.
dotnet add package JsxCore
With a Minimal API, you register JsxCore and return a view. Build the model in C# and hand it to a .tsx view:
using JsxCore.Hosting;
using JsxCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.AddJsxCore();
var app = builder.Build();
app.UseJsxCore();
app.MapGet("/", () => Results.Extensions.Jsx("Home/Index", new { name = "World" }));
app.Run();
// Views/Home/Index.tsx
export default function Index({ model }: { model: { name: string } }) {
return <h1>Hello {model.name}</h1>;
}
In a real editor, the C# Program.cs and the .tsx view sit side by side. Notice the .tsx line import type { IndexModel } from "dotnet:SampleApp.React" — your C# model type is pulled straight into TypeScript through the dotnet: scheme.
![Rider showing Program.cs (registering JsxCore and returning a Jsx view from a Minimal API, with a [JsxModel] record) next to Index.tsx (importing types from dotnet: and using React's useState)](https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmki6symgjl3ke23w0qdu.png)
C# Program.cs and Index.tsx. The dotnet: import brings C# types into the TSX side (source: JsxCore repository).
How it works — calling C# straight from a view
The key idea is that server rendering runs inside the .NET process. Because there's no separate Node.js process in the middle, a view can call your C# services synchronously, with no bridge overhead. You don't have to round-trip through an API to fetch data; the view can reach straight into your application logic.
The screenshot below is the sample app's ".NET globals" tab. The total stock value, the server time, and a low-stock list are all read from a C# service while the page renders. The front-end component has a direct line into the .NET world.

C# services are called during rendering to draw the stock value and server time (source: JsxCore repository).
On top of that, JsxCore generates TypeScript type definitions from your C# view models. That prevents the server/client "drift" where types silently diverge, and your .tsx gets written against generated, type-safe models. TypeScript and esbuild are handled with zero configuration, so you don't lose time wiring up the toolchain.
Developer experience — comfortable without Node.js
The DX details are where JsxCore shines. You can install and use npm packages without Node.js installed. TypeScript type errors show up instantly on hot reload, surfaced as a browser overlay right on the page. In the example below, Index.tsx(15,7) reports TS2322 (string is not assignable to number) — the feedback loop is fast.

Hot reload surfaces TypeScript compilation errors as a browser overlay (source: JsxCore repository).
The render mode is configurable — AddJsxCore(options => options.DefaultRenderMode = RenderMode.ServerAndClient) gives you a "server + client" mode that paints fast on the server and then hydrates for interactivity. React's useState, hooks, and ESM import all work as usual, so the learning curve for React developers is small.
What it means for .NET teams
JsxCore is a strong fit when your backend is .NET and you want the feel of React/TypeScript on the front end. You get first-paint server rendering for SEO and post-click interactivity from a single component model, and you can reach C# assets without an API hop or serialization. Keeping your React skills while dropping the Node.js runtime and a separate build pipeline is a real maintenance win.
That said, JsxCore is a young project (a few dozen GitHub stars at the time of writing), and its API and rendering behavior may still move. Before adopting it in production, try your own use cases (auth, streaming, large pages) against the sample app and make sure you can keep up with updates. Unlike Blazor, which is "all C#," JsxCore is about bringing React/TSX skills and assets into .NET — so pick it based on your team's skill set.
What the community is saying
The heads-up came from the author himself: server and client rendering, hooks, ESM imports, direct binding to C#, and transparent TypeScript type generation for server-side code — "it's really cool, coming soon," with follow-ups about native React support for ASP.NET Core MVC aimed at people used to Next.js.
The reaction reflects real enthusiasm for full-stack C#. Developer Luke Parker riffed on it — half-joking that he'd "decided to rewrite opencode in C#" — a sign that "C# all the way to the front end" is genuinely moving people.
FAQ
Do I need Node.js to use JsxCore?
No. You only need the .NET SDK; JsxCore handles TypeScript compilation, esbuild, and even fetching npm packages. There's no Node.js runtime to provision in dev or prod.
Can I use React and Preact?
Both. Preact ships built-in and React is available via restoration. Standard React idioms — useState, hooks, ESM imports — work as-is.
How is this different from Blazor?
Blazor writes UI in C# and Razor — an "all-C#" approach. JsxCore instead brings JSX/TSX and React/Preact into ASP.NET Core, so you can reuse existing React/TypeScript knowledge and code. Choose based on your team's skills and what you want from the front end.
References
Originally published on WithNext.NET, where we write about .NET modernization, performance, and applied AI.


Top comments (1)
The
dotnet:import that turns C# view models into TypeScript definitions is the most compelling part here, because it removes a whole class of contract drift without adding a separate schema pipeline. Running server rendering inside the.NET process and calling C# services directly also makesServerAndClientappealing, though I'd keep those view dependencies narrow so rendering doesn't quietly become the application layer. For a young library, the production test isn't just hooks or hot reload-it's whether auth, caching, failure isolation, and dependency restoration remain predictable under deployment pressure.