In this article, we will explore the two popular libraries for generating OpenAPI documentation in C#: Swashbuckle and NSwag. We’ll compare their features, ease of use, and other factors that will help us choose the best one for our projects.

To download the source code for this article, you can visit our GitHub repository.

Let’s start.

What are Swashbuckle and NSwag Used for?

Swashbuckle and NSwag are two popular libraries in the C# ecosystem that we can use to generate OpenAPI documentation.

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

OpenAPI, formerly known as Swagger, is a widely adopted standard for RESTful API documentation. We can use it to describe the structure of our APIs, making it easier for others to understand and consume them. By using it we can generate interactive API documentation that allows consumers to explore and test our API endpoints.

What’s more, the OpenAPI specification also allows us to generate client libraries for various programming languages, making it easier to integrate our APIs into different applications.

Let’s dive into each of them and understand their differences.

What is Swashbuckle?

We will start with Swashbuckle, which is a popular open-source library for generating API documentation for ASP.NET Core applications.

We can use it to automatically generate an OpenAPI specification based on our controllers, routes, and models, allowing us to serve up interactive, browser-based documentation with minimal effort.

Now, let’s have a look at an example of generated documentation:

API Using swashbuckle nswag

On top of that, it offers various customization options, such as adding XML comments to generated documentation, modifying operation tags and descriptions, and customizing UI appearance.

Example Usage of Swashbuckle

First, we need to install Swashbuckle. To do that we simply need to run the Nuget command:

Install-Package Swashbuckle.AspNetCore -Version 6.5.0

Or we can use the .Net CLI command:

dotnet add package Swashbuckle.AspNetCore

Then we have to register Swagger in ConfigurationServices method in Startup.cs file:

public void ConfigureServices(IServiceCollection services)
{
    // Add Swashbuckle to our services
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
    });

    services.AddControllers();
}

This will add the Swagger generator to our collection of services.

After that, we need to enable middleware to serve generated Swagger as a JSON endpoint and Swagger UI. We can do this by modifying our Configure method:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // Enable middleware to serve generated Swagger as a JSON endpoint and Swagger UI
    app.UseSwagger();

    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    });
}

At this point, we are ready to start utilizing Swagger in our project.

What is NSwag?

Now let’s talk about NSwag, which is another powerful library for generating OpenAPI Specification documents and client code from .NET applications.

It supports both .NET Framework and .NET Core and offers additional features like code generation.

As we can read on the GitHub page of the project, NSwag is intended to combine functionalities of two other libraries: Swashbuckle for OpenAPI generation and AutoRest for client generation. 

Example Usage of NSwag

To install it we simply need to run this command:

Install-Package NSwag.AspNetCore -Version 13.18.2

Alternatively, we can use the .Net CLI command:

dotnet add package NSwag.AspNetCore

Once we have NSwag installed we have to add it to our services collection within the ConfigurationServices method in our Startup.cs file:

public void ConfigureServices(IServiceCollection services)
{
    // Register the NSwag services
    services.AddOpenApiDocument(config =>
    {
        config.DocumentName = "v1";
        config.Title = "My API";
        config.Version = "v1";
    });

    services.AddControllers();
}

After that, we have to modify our Configure method:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseOpenApi();
    app.UseSwaggerUi3();
}

Once we complete these steps we are ready to use NSwag.

Now that we know some basic information about both libraries, we can take a deep dive into a comparison of the features they provide.

API Documentation Generation

We will start with the primary feature, which is API documentation generation.

It’s no surprise that both Swashbuckle and NSwag excel at generating API documentation based on our controllers and actions. They inspect our code to create an OpenAPI specification document, which we can serve as interactive documentation through the Swagger UI or ReDoc UI.

Additionally, both libraries can provide documentation in either JSON or YAML formats.

In Swashbuckle we can achieve that by modifying the Configure method:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 
{ 
    // Enable middleware to serve generated Swagger as a JSON endpoint and Swagger UI 
    app.UseSwagger();
    app.UseSwaggerUI(c => 
    { 
        c.SwaggerEndpoint("/swagger/v1/swagger.yaml", "My API V1"); 
    }); 
}

As we can see, we just need to specify the .yaml extension in our SwaggerEndpoint configuration.

And respectively for NSwag:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{
    app.UseOpenApi(p => p.Path = "/swagger/v1/swagger.yaml");
    app.UseSwaggerUi3(p => p.DocumentPath = "/swagger/v1/swagger.yaml");
}

Here, we need to do a bit more work. 

Firstly, we modify the Path property specifying the .yaml format when calling UseOpenApi method. Then in the same way we need to modify our DocumentPath property when we call the UseSwaggerUi3 method.

All in all, both libraries allow API consumers to explore and test our API endpoints in a user-friendly manner. And if the only feature we need is generating documentation for our APIs, then either of these libraries is a solid choice.

Swagger UI Customization

Swagger UI is a popular interactive documentation tool we can customize to match our API’s branding or style requirements. Both Swashbuckle and NSwag support Swagger UI customization.

If we would like to modify it we have a few options to choose from.

We can copy the content of the Swagger UI repository to the wwwroot/swagger/ui folder in our project and modify the required files.

Or we can simply inject the style sheet directly into Swagger UI, like so:

app.UseSwaggerUI(c => 
{ 
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); 
    c.InjectStylesheet("/custom.css");
});

And since this is a feature of Swagger UI itself, it will work the same way for both Swashbuckle and NSwag.

Customers and Orders endpoints in swashbuckle nswag

Or if we prefer, we can also use ReDoc UI.

First, we need to add a dependency to the Swashbuckle.AspNetCore.ReDoc package. Then we need to call app.UseRedoc() instead of app.UseSwaggerUi().

Lastly, because ReDoc is exposed via/api-docs we can change this when enabling middleware by setting RoutePrefix:

app.UseReDoc(c =>
    c.RoutePrefix = "swagger"
);

In contrast, this transition is much easier with NSwag. We simply need to call app.UseReDoc() instead of app.UseSwaggerUi3() and we are done.

As a result, we can see ReDoc UI:

Get Request

Code generation

Code generation is a feature that allows us to quickly generate clients for our APIs for different programming languages. 

While this feature is useful and can speed up our development process, Swashbuckle does not have built-in support for generating client code directly. It can be used in combination with other tools or libraries that consume OpenAPI specification files to generate client code. 

NSwag, on the other hand, provides us with a set of code generation features and can generate client code for C# or TypeScript.

In addition, it offers multiple ways to generate code, such as using the NSwagStudio GUI, the NSwag CLI, or integrating NSwag directly into our project as a middleware or build tool.

Let’s take a look at how we can easily generate a TypeScript client using NSwagStudio. We just need to launch it and provide it with the URL to our Swagger documentation swagger.json file:

nswag-studio-input

Then select the output format and click Generate Outputs:

nswag-studio-output

And with those simple steps, we have our client ready to be used in consumer applications.

Support of Authentication Configuration

To take things to the next level, let’s have a look at how we might configure a layer of authentication to secure our API.

Both Swashbuckle and NSwag support various authentication configurations, allowing us to secure our API and its documentation. 

Swashbuckle provides support for several authentication methods, including OAuth2, API keys, and JWT (JSON Web Tokens).

Now, let’s take a look at a short example.

We will modify our Startup.cs file and set up authentication for our API documentation in Swashbuckle using JWT:

public void ConfigureServices(IServiceCollection services) 
{ 
    //Setup JWT Authentication
    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        var key = Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]);
        
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidIssuer = Configuration["Jwt:Issuer"],
            ValidAudience = Configuration["Jwt:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(key),
            ValidateIssuer = false,
            ValidateAudience = false,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true
        };
    });

    // Add Swashbuckle to our services 
    services.AddSwaggerGen(c => 
    { 
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }); 
        
        // Configure authentication for Swagger
        c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
        {
            Description = "JWT Authorization header using the Bearer scheme.",
            Type = SecuritySchemeType.Http,
            Scheme = "bearer"
        });

        c.AddSecurityRequirement(new OpenApiSecurityRequirement
        {
            {
                new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }
                },
                Array.Empty<string>()
            }
        });
    }); 
    
    services.AddControllers(); 
}

The first thing we do is configure JWT authentication. We do this by registering JWT middleware using the AddAuthentication method. Next, we use the AddJwtBearer method to enable JWT authentication and configure bearer options.

Then, we modify the Swashbuckle configuration to enable authentication using the bearer schema by calling AddSecurityDefinition and AddSecurityRequirement methods. 

NSwag supports a similar range of authentication methods as Swashbuckle, including OAuth2, API keys, and JWT.

And again, let’s check out a short example.

We can set up authentication for our API documentation in NSwag by modifying our Startup.cs file and adding OAuth2 authentication:

public void ConfigureServices(IServiceCollection services) 
{ 
    //Configure OAuth2 authentication
    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = "Bearer";
        options.DefaultChallengeScheme = "Bearer";
    })
    .AddOpenIdConnect("Bearer", options =>
    {
        // Configure OpenID Connect options here
        options.Authority = Configuration("OAuth2:Authority");
        options.ClientId = Configuration("OAuth2:ClientId");
        options.ClientSecret = Configuration("OAuth2:ClientSecret");
        options.ResponseType = OpenIdConnectResponseType.Code;
        options.Scope.Clear();
        options.Scope.Add("openid");
        options.Scope.Add("profile");
        options.Scope.Add("email");
        options.Scope.Add("api");
        options.SaveTokens = true;
    });

    // Add NSwag to our services 
    services.AddOpenApiDocument(config =>
    {
        config.DocumentName = "v1";
        config.Title = "My API";
        config.Version = "v1";

        // Configure OAuth2 authentication for NSwag
        config.AddSecurity("OAuth2", Enumerable.Empty<string>(), new OpenApiSecurityScheme
        {
            Type = SecuritySchemeType.OAuth2,
            Flows = new OpenApiOAuthFlows
            {
                AuthorizationCode = new OpenApiOAuthFlow
                {
                    AuthorizationUrl = Configuration("OAuth2:AuthorizationUrl"),
                    TokenUrl = Configuration("OAuth2:TokenUrl"),
                    Scopes = new Dictionary<string, string>
                    {
                        { "openid", "OpenID Connect" },
                        { "profile", "User profile" },
                        { "email", "User email" },
                        { "api", "Access to API" }
                    }
                }
            }
        });

        config.OperationProcessors.Add(new OperationSecurityScopeProcessor("OAuth2"));
    });
    
    services.AddControllers(); 
}

Firstly, we configure the authentication scheme through the use of the OpenID Connect authentication middleware.

Then, we modify the NSwag configuration to enable OAuth2 authentication with our AddSecurity method, and utilize OperationProcessors to implement OAuth2.

Now, when we access the UI generated by NSwag, we will see an Authorize button that allows users to authenticate using our OAuth2 provider. Once authenticated, users can automatically (and securely!) make API calls with the appropriate access token.

Performance Comparison

Both Swashbuckle and NSwag have similar performance profiles, meaning that both libraries are suitable for small to large projects.

We have to remember that both libraries focus on generating API documentation and client code, which are typically one-time or infrequent operations during the development process.

Thus, the performance overhead introduced by these libraries is minimal, as they primarily generate static documentation and client code. Therefore there is a slight overhead during app startup, but after that, it is usually negligible.

And indeed, we use the BenchmarkDotNet package to investigate those differences:

|                   Method |     Mean |     Error |   StdDev |  Allocated |
|--------------------------|---------:|----------:|---------:|-----------:|
| Swashbuckle_PostResponse | 6.861 ms | 0.6065 ms | 1.788 ms |  919.91 KB |
|       NSwag_PostResponse | 8.287 ms | 0.9454 ms | 2.728 ms | 1156.43 KB |
|  Swashbuckle_GetResponse | 5.833 ms | 0.4129 ms | 1.205 ms |  958.58 KB |
|        NSwag_GetResponse | 8.740 ms | 1.1480 ms | 3.312 ms | 1060.64 KB |

As we can see the difference is less than 2ms in favor of Swashbuckle on both POST and GET endpoints.

It’s worth noting that NSwag’s code generation feature might add additional overhead, especially when generating code for multiple languages or large APIs. However, due to its infrequent usage, it is normally not a consideration for application runtime performance.

Ease of Use

Next, let’s look at how easy is it to use each library.

Both Swashbuckle and NSwag provide us with a straightforward setup process, and our earlier setup examples demonstrate how quickly they allow us to get started.

Here, though, we encounter one of the biggest advantages of Swashbuckle. Since .NET 6 and Visual Studio 2022, Swashbuckle is natively supported by built-in project templates. This means that we can easily add Swagger to our APIs using the new project creator.

When we create new API projects we simply need to tick a checkbox next to the Enable OpenApi support option:

visual-studio-openapi-support

And as simple as that, a Swashbuckle dependency will be added to our project, and all necessary configurations applied to our code.

On the other hand, if we want to use NSwag, the configuration process is a manual one (albeit not too tedious).

Compatibility Considerations

Another point to consider when deciding whether we should use Swashbuckle or NSwag is compatibility with different versions of the .NET Framework.

Swashbuckle supports both ASP.NET Core and the older ASP.NET also known as ASP.NET MVC/WebAPI. However, the integration process and package names are different for each version. For ASP.NET Core, we would use the Swashbuckle.AspNetCore package, while for the older ASP.NET MVC/WebAPI projects, we should use the Swashbuckle package.

We have a similar situation with NSwag, it is compatible with both .NET Framework and .NET Core. And we have to reference the appropriate package for our needs. For ASP.NET Core, we would use the NSwag.AspNetCore package, while for the older ASP.NET MVC/WebAPI projects, we should use the NSwag.AspNet.WebApi package.

So, both Swashbuckle and NSwag support ASP.NET Core and the older ASP.NET MVC/WebAPI. Both offer impressive versatility for projects based on different .NET frameworks.

Community Support

Finally – and very importantly – we come to community support. Even the greatest library will have limited usefulness without the support of the community and their ongoing development, enhancement, troubleshooting, and bug-fixing efforts. These are indispensable, especially when we are talking about open-source projects.

Swashbuckle enjoys more community support because of its maturity. To this day it has been downloaded over 324 million times.

It has a large and active community that contributes to the project, provides support, and shares knowledge. The main GitHub repository for Swashbuckle.AspNetCore has over 4.8 thousand stars and over 1.2 thousand forks. And what’s more, it reports that almost 450 thousand projects are using it.

There are numerous blog posts, tutorials, and Stack Overflow answers available that cover various aspects of Swashbuckle usage and configuration. If we encounter issues or need help, we can often find answers on Stack Overflow, GitHub issues, or other community forums.

And as we have noted, even Microsoft provides native support for it in Visual Studio 2022.

On the other hand, NSwag is gaining popularity and has an active community that continues to help with its development.

While it may not be as widely known as Swashbuckle, it still has a strong and active community. The main GitHub repository for NSwag has over 5.9 thousand stars and 1.1 thousand forks. But reports that only over 2300 project uses it.

Similarly to Swashbuckle, there are numerous blog posts, tutorials, and Stack Overflow answers available that cover various aspects of NSwag usage and configuration.

All in all, both libraries have a good number of contributors and resources available for learning and troubleshooting. Swashbuckle is more widely-known and has a larger community, which may result in slightly more resources and community support. However, NSwag also has a strong and active community, making it a viable choice as well.

Conclusion

All in all, both Swashbuckle and NSwag excel in generating API documentation. Both libraries are great options, with similar capabilities and performance. If you favor a smoother setup experience with just a few clicks in Visual Studio, you might prefer Swashbuckle. On the other hand, if requirements include client code generation, then NSwag may be the tool to use. Or maybe mix it up with documentation from Swashbuckle and code generated by NSwagStudio. Fortunately, with these two ecosystems, there is no wrong choice.
Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!