What Is Scalar? Why Use Scalar Instead of Swagger UI in ASP.NET Core 10
Scalar is an open-source API Reference UI that replaces Swagger UI, and it is what Microsoft recommends for ASP.NET Core from .NET 9 onward. Starting with .NET 9, Microsoft removed Swashbuckle (Swagger UI) from the default Web API template and replaced it with Microsoft.AspNetCore.OpenApi combined with Scalar. This post explains the reasoning behind that change, compares Scalar against Swagger UI feature by feature, and walks through setting Scalar up in ASP.NET Core 10 — both for a brand new project and as a migration from an existing one.
If you created a new ASP.NET Core Web API project on .NET 9 or .NET 10 and were surprised to find Swagger UI missing, you are not alone. Microsoft deliberately replaced Swashbuckle with a native OpenAPI pipeline, and Scalar is the UI recommended alongside it.
TL;DR
- .NET 9+: Microsoft dropped Swashbuckle from the
dotnet new webapitemplate - The replacement:
Microsoft.AspNetCore.OpenApi(document generation) +Scalar.AspNetCore(UI) - The OpenAPI JSON now lives at
/openapi/v1.jsoninstead of/swagger/v1/swagger.json - The Scalar UI is served at
/scalar/v1 - Migrating away from Swashbuckle takes roughly 15–30 minutes
Why did Microsoft drop Swagger UI (Swashbuckle)?
Swashbuckle is a third-party library that is no longer actively maintained
Swashbuckle.AspNetCore is a community package, not a Microsoft one. From .NET 9, Microsoft decided it needed a first-party solution integrated deeply into the ASP.NET Core pipeline rather than depending on an external package whose maintenance lifecycle offers no guarantees.
Microsoft.OpenApi v2 is a breaking change that Swashbuckle cannot absorb
Microsoft.OpenApi 2.x, which ships with .NET 10, is a complete breaking change from the 1.x line that Swashbuckle 6.x–9.x depends on. Swashbuckle cannot build cleanly on .NET 10 because the new object model is not backward compatible.
The native OpenAPI pipeline produces more standards-compliant OpenAPI 3.1
Microsoft.AspNetCore.OpenApi — the package that ships in-box from .NET 9 — generates OpenAPI 3.1 straight from endpoint metadata. No elaborate reflection, full Native AOT support, and clean integration with both Minimal APIs and controller-based APIs.
No. Swashbuckle is still a community package and still works on .NET 10. What changed is that it is no longer part of the default template — you have to opt in yourself if you want it.
What is Scalar?
Scalar is an open-source API Reference UI that reads OpenAPI 3.1 and renders it as interactive API documentation. It plugs into ASP.NET Core through the Scalar.AspNetCore NuGet package.
Scalar only reads the JSON file; generating the document is ASP.NET Core's job:
Scalar is not merely "a prettier Swagger UI" — it brings a number of features of its own:
- Dark mode out of the box — no custom theme required
- 11 built-in themes (
moon,purple,solarized,deepSpace,laserwave, and more) - A built-in API client: request history, environment variables, code snippets for 25+ languages
- Sidebar navigation for APIs with a large number of endpoints
- Full-text search built in (Swagger UI needs a separate plugin for this)
- A CORS proxy so cross-origin API testing does not fail
Scalar vs Swagger UI
| Feature | Scalar | Swagger UI |
|---|---|---|
| OpenAPI 3.1 | ✅ | ✅ |
| OpenAPI 3.2 | 🔄 in progress | ❌ not planned |
| .NET 9/10 native pipeline | ✅ | ❌ |
| Dark mode | ✅ | ❌ |
| Built-in themes | 11 themes | ❌ |
| Sidebar navigation | ✅ | ❌ |
| Full-text search | ✅ built in | ⚠️ needs a plugin |
| Code snippet generation | 25+ languages | ⚠️ limited |
| Vue component | ✅ | ❌ |
| CORS proxy | ✅ | ❌ |
| Desktop API client | ✅ | ❌ |
| PRs merged in 2025 | 2,075 | 176 |
The takeaway: Scalar has a far more active community (~12× the merged PRs in 2025), ships more features, and is what Microsoft picked as the default UI for ASP.NET Core from .NET 9 on.
Setting Scalar up on ASP.NET Core 10 (from scratch)
Step 1: Create a new Web API project
dotnet new webapi -n MyApi
cd MyApi
On .NET 10 the template already includes Microsoft.AspNetCore.OpenApi. All you need to add is Scalar:
dotnet add package Scalar.AspNetCore
Step 2: Configure Program.cs
using Scalar.AspNetCore;
var builder = WebApplication.CreateBuilder(args);
// Register OpenAPI document generation
builder.Services.AddOpenApi();
var app = builder.Build();
// Only expose the docs in the Development environment
if (app.Environment.IsDevelopment())
{
app.MapOpenApi(); // generates /openapi/v1.json
app.MapScalarApiReference(); // renders the UI at /scalar/v1
}
app.UseHttpsRedirection();
// A Minimal API example
app.MapGet("/products", () =>
Results.Ok(new[]
{
new { Id = 1, Name = "Laptop", Price = 25_000_000 },
new { Id = 2, Name = "Mouse", Price = 350_000 }
})
)
.WithName("GetProducts")
.WithSummary("Get the product list")
.WithDescription("Returns every product currently available in the system.");
app.Run();
Once it is running, these are the URLs you get:
| URL | Description |
|---|---|
https://localhost:{port}/openapi/v1.json | The OpenAPI JSON document |
https://localhost:{port}/scalar/v1 | The Scalar UI |
Step 3: Update launchSettings.json
So that F5 opens Scalar instead of a blank page, edit Properties/launchSettings.json:
{
"profiles": {
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "scalar/v1",
"applicationUrl": "https://localhost:7001;http://localhost:5001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Step 4: Customise the Scalar UI (optional)
app.MapScalarApiReference(options =>
{
options.Title = "My API Reference";
options.Theme = ScalarTheme.Moon;
options.DefaultHttpClient = new(ScalarTarget.CSharp, ScalarClient.HttpClient);
options.DarkMode = true;
});
Available themes: Default, Alternate, Moon, Purple, Solarized, BluePlanet, Saturn, Kepler, Mars, DeepSpace, Laserwave.
Migrating from Swashbuckle to Scalar
If you have a .NET 8 or older project still on Swashbuckle, here is the full migration path.
Step 1: Remove Swashbuckle
dotnet remove package Swashbuckle.AspNetCore
dotnet remove package Swashbuckle.AspNetCore.Annotations # if present
dotnet remove package Swashbuckle.AspNetCore.Filters # if present
Step 2: Add the new packages
dotnet add package Microsoft.AspNetCore.OpenApi
dotnet add package Scalar.AspNetCore
Step 3: Update Program.cs
Before — Swashbuckle:
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
});
// ...
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
After — Microsoft.AspNetCore.OpenApi + Scalar:
builder.Services.AddOpenApi();
// ...
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
app.MapScalarApiReference();
}
Step 4: Update your URLs
| Before (Swashbuckle) | After (Scalar) |
|---|---|
/swagger/v1/swagger.json | /openapi/v1.json |
/swagger | /scalar/v1 |
Update everywhere the old URL is hardcoded: CI pipelines, API gateway imports, client generator configuration.
If you need a zero-downtime migration, ship both in one release: keep Swashbuckle serving /swagger/... while Scalar serves /openapi/.... Once every consumer has moved to the new URL, drop Swashbuckle.
Adding API metadata with a document transformer
To have Scalar display complete information (title, version, contact), add a document transformer:
builder.Services.AddOpenApi(options =>
{
options.AddDocumentTransformer((document, context, cancellationToken) =>
{
document.Info = new()
{
Title = "My API",
Version = "v1",
Description = "API documentation generated automatically by ASP.NET Core 10",
Contact = new()
{
Name = "Tien NHM",
Url = new Uri("https://tiennhm.github.io")
},
License = new()
{
Name = "MIT",
Url = new Uri("https://opensource.org/licenses/MIT")
}
};
return Task.CompletedTask;
});
});
Securing the /openapi and /scalar endpoints in production
By default the docs are only exposed in the Development environment. If you do need them in production — an internal portal, say — add authorization:
// Only users in the "Admin" role can reach the docs
app.MapOpenApi().RequireAuthorization("AdminOnly");
app.MapScalarApiReference().RequireAuthorization("AdminOnly");
Frequently asked questions (FAQ)
Is Scalar free?
Yes. Scalar is open source (MIT license) and completely free. The Scalar.AspNetCore package on NuGet is free as well.
Has Swagger been removed entirely in .NET 10?
No. Swashbuckle is still a community package and it still works on .NET 10. What changed is that it is no longer part of the default dotnet new webapi template from .NET 9 onward.
Does Scalar support controller-based APIs, or only Minimal APIs?
It supports both. Microsoft.AspNetCore.OpenApi generates the document from Minimal APIs and controller-based APIs alike, and Scalar only reads the OpenAPI JSON file, so it does not care how the API was defined.
Can I run Scalar and Swagger UI at the same time?
Yes. The two UIs are entirely independent and both read the same OpenAPI JSON file. That is exactly what makes for a safe migration: run both in parallel, then turn the old one off once everything has moved across.
Where does the OpenAPI JSON live now?
From .NET 9 with Microsoft.AspNetCore.OpenApi, the document sits at /openapi/v1.json instead of Swashbuckle's /swagger/v1/swagger.json. This is the detail most often missed during a migration, and it breaks CI pipelines and API gateway imports.
Does Scalar support OAuth2 authentication?
Yes. Scalar supports OAuth2 with the PKCE flow, API keys, and bearer tokens. You can pre-fill authentication credentials through the Authentication options.
Conclusion
Microsoft dropping Swashbuckle from the default template is a sign of a maturing .NET ecosystem moving toward first-party solutions. The Microsoft.AspNetCore.OpenApi + Scalar.AspNetCore pairing is the sensible default for ASP.NET Core 10:
- Standards-compliant OpenAPI 3.1 generation with Native AOT support
- A modern interface with dark mode and 11 themes to pick from
- A built-in API client with code snippets for 25+ languages
- Fewer external dependencies, with first-party support from Microsoft
- An actively maintained community project (2,075 PRs merged in 2025)
If you are starting a new project on .NET 10, reach for Scalar from day one. For an existing project on Swashbuckle, the migration in this post takes about 15–30 minutes.
References
- Scalar — Official Website
- Migrate from Swagger UI to Scalar
- Microsoft Docs — Using OpenAPI documents in ASP.NET Core
- Combining API versioning with OpenAPI in .NET 10 — .NET Blog
- Swashbuckle Is Dead. Here's How to Migrate to Scalar in .NET 10
- ASP.NET Core Dropped Swagger — Here's What Replaced It in .NET 10
