Development Workflow
In development you run two processes: the Vite dev server (which serves your SPA modules with hot
module replacement) and your ASP.NET Core app (which serves the Razor page hosting the SPA). The
<dev-vite-scripts> helper stitches them together.
Running the two processes
Section titled “Running the two processes”-
Start the Vite dev server from the SPA folder:
Terminal window cd ReactAppnpm run devWhen the server begins listening, the plugin writes
wwwroot/ReactApp/manifest.dev.jsonwith the server’s port, your entrypoint, the container id, and whether the app is React. -
Run the ASP.NET Core app:
Terminal window dotnet run -
Open the page.
<dev-vite-scripts>reads the manifest and loads the Vite client and your entrypoint fromhttp://localhost:{port}, giving you HMR inside the Razor page.
If the dev server isn’t running
Section titled “If the dev server isn’t running”If you load the page before the Vite dev server is listening, <dev-vite-scripts> renders a
“Vite Dev Server Not Found” message and retries fetching the entrypoint for a short window.
Start npm run dev and refresh, and the SPA mounts. This is expected behavior, not an error in
your setup.
Launching the dev server from .NET (optional)
Section titled “Launching the dev server from .NET (optional)”To avoid running two terminals, you can have ASP.NET Core start the Vite dev server for you with the
RunViteDevServer extension (in the ViteDotNet.NPM namespace). Call it during startup in
development:
using ViteDotNet.NPM;
var app = builder.Build();
if (app.Environment.IsDevelopment()){ app.RunViteDevServer();}There’s nothing to pass: the SPA folder comes from your ViteDotNet configuration, and the port is
whatever the dev server binds to — the plugin records it in manifest.dev.json, so neither the
directory nor the port is configured here.
When more than one app is configured, name the one to launch — calling it once per app:
app.RunViteDevServer("ReactApp");app.RunViteDevServer("SvelteApp");Each call runs that app’s dev npm script in its SPA folder.
The command starts once your app is up and listening, so a single dotnet run brings up both
processes. The call returns immediately — there’s no Task to await — and the dev server is
terminated together with your app when it shuts down.
When you’re ready to ship, see Production Builds.