Read More on Telerik Blogs
July 22, 2025 Web, ASP.NET Core
Get A Free Trial

NuGet packages are a fundamental component of .NET and help speed up development without having to reinvent the wheel. Learn in this post how to create your own NuGet package, publish it and use it in your applications.

NuGet packages provide a wide range of features to accelerate ASP.NET Core web development. With them, developers can access everything they need with just a few clicks or commands.

In this post, we will see how NuGet packages work and then implement our package, publish it on the official NuGet website and install it in a web application.

📦 What Is NuGet?

NuGet is a mechanism through which developers can create, share and consume useful code resources for a variety of purposes.

This code is grouped into “packages” that contain the content needed by the projects that consume it, such as DLLs, algorithms, configuration files, static resources and metadata.

In simple terms, a NuGet package is a ZIP file with the extension .nupkg that brings together DLLs (already compiled code), related auxiliary files and a manifest with important information such as the package version, its dependencies and author details.

🛠️ How Does NuGet Work?

1. Package Creation

A developer creates code in a project (typically a Class Library), and bundles the compiled code (DLLs), supporting files and a manifest (.nuspec) into a package, with a .nupkg extension.

2. Publishing

This package is published to a NuGet repository, such as nuget.org, or to a private repository (such as an internal company feed or Azure Artifacts).

3. Consumption

Another developer adds the package to their project via Visual Studio, by CLI (dotnet add package) or manually by editing the .csproj file. NuGet automatically resolves the dependencies and downloads the necessary packages.

4. Restoration

When the project is built or restored, NuGet downloads all the necessary packages and dependencies, then caches them locally for reuse.

5. Version Management

NuGet allows you to specify exact versions (1.0.0), ranges (1.0.1) or accept the latest compatible version, which helps maintain project stability and facilitates controlled upgrades.

The image below summarizes this process:

⛏️⬆️ Creating and Publishing a NuGet Package

Now that we understand the basics of what a NuGet package is and how it works, we will see in practice how to implement a functionality that can be shared between .NET applications through the NuGet package manager.

Imagine that you are developing the backend of a blog, but you would like the main functionalities to be reusable. That way, every time you need to create a new blog, you would not need to rewrite the same code.

To put this into practice, we will create the NuGet package, publish it and then create a project for the blog and use the newly created function.

You can check out the complete project covered in the post, in this GitHub repository: Creating a NuGet Package.

So, to create the base application, you can use the command below in the terminal:

dotnet new classlib -n Dango.BlogUtils

Note that the template used is classlib, which is typically used to create classes with shared functionality like NuGet packages. Also, the name of the library Dango.BlogUtils, is inspired by the Japanese sweet dango 🍡, made from sticky rice balls and usually served on skewers.

You can, of course, choose whatever name you like. The main point here is to emphasize the importance of using creative names when creating new libraries. A good name not only makes your code more identifiable and organized, but it also makes it easier for other developers to adopt it, especially if you plan to share or publish it as a package.

Now, open the project and, inside it, create a new class called SlugGen. Inside that, add the following code:

using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;

namespace Dango.BlogUtils;

public static class SlugGen
{
    public static string GenerateSlug(string input)
    {
        if (string.IsNullOrWhiteSpace(input))
            return string.Empty;

        string normalized = input.Normalize(NormalizationForm.FormD);
        var stringBuilder = new StringBuilder();

        foreach (var c in normalized)
        {
            var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
            if (unicodeCategory != UnicodeCategory.NonSpacingMark)
                stringBuilder.Append(c);
        }

        string result = stringBuilder.ToString().Normalize(NormalizationForm.FormC);
        result = Regex.Replace(result.ToLowerInvariant(), @"[^a-z0-9\s-]", "");
        result = Regex.Replace(result, @"\s+", "-").Trim('-'); 
        result = Regex.Replace(result, @"-+", "-");

        return result;
    }
}

Let’s take a look at this code. First, we define a static class called SlugGen, which is responsible for generating slugs from an input string. A slug is a simplified, “URL-friendly” version of text, often used in webpage addresses to represent article titles or resource names. A common example of a slug:

  • Plain text: Hello, welcome to the blog!
  • Slug: hello-welcome-to-the-blog

The main method, GenerateSlug, takes a string as a parameter and returns another string, which is the corresponding slug. First, a check is made to see if the input is null, empty or composed only of whitespace. If this is the case, the method returns an empty string, avoiding unnecessary processing.

The text is then normalized using the FormD form, which separates accented characters from their base form. This allows characters that belong to the NonSpacingMark category (such as accents) to be removed from the text immediately afterwards. This removal is done using StringBuilder, which stores only the characters considered relevant.

The string is then normalized again, this time using FormC, to reconstruct the characters into their most compact canonical form. With this cleaned-up version of the string, the characters are converted entirely to lowercase, removing all characters that are not lowercase letters, numbers, spaces or hyphens, using a regular expression.

Next, whitespace is replaced with hyphens, and any hyphens at the beginning or end of the string are removed. Finally, multiple consecutive hyphens are replaced with a single hyphen. The end result is a clean, readable slug that is suitable for use in friendly URLs.

Now, our package is ready to be published.

Publishing the Package on NuGet Org

The first step before publishing is to generate a release, which will contain the packaged binary files. To do this, simply open a terminal in the application root and run the following command:

dotnet pack -c Release

This command will create the package and save it in: bin/Release/Dango.BlogUtils.1.0.0.nupkg.

Now, we need to configure the NuGet Org website. Then, go to the address: www.nuget.org. Log in with a Microsoft account, then click on your username and click on the “API Keys” option:

Then, click on the Create menu and fill in the data:

  • Key Name: This will be the name of the API key, so use a descriptive name.
  • Check the option: Push new packages and package versions.
  • Glob Pattern: This property will indicate which namespaces can be published, in this example, using the name Dango.* means only packages that start with the name Dango. can be published.

Finally, click on Create.

Remember to copy the newly created API key and leave it somewhere accessible. We will need it later.

Now we can push the package to the NuGet host. To do this, simply run the following command in a terminal at the root of the application.

dotnet nuget push bin/Release/Dango.BlogUtils.1.0.0.nupkg \
--api-key YOUR_API_KEY\
--source https://api.nuget.org/v3/index.json

Replace YOUR_API_KEY with the API key you just created.

If everything goes well, you should see something like this in the terminal:

Pushing Dango.BlogUtils.1.0.0.nupkg to 'https://api.nuget.org/v3/index.json'... 
PUT https://www.nuget.org/api/v2/package/ 
Created https://www.nuget.org/api/v2/package/ 5716ms
Your package was pushed.

Using the NuGet Package in a Web Application

At this point, the package is ready to be downloaded and installed. So, to test this, we will create a simple API that will receive any text and return the corresponding slug.

So, you can use the following command to create the API project:

dotnet new web -o SweetNewsBlog

Then, open the application and in the project root, execute the command below in a terminal to download the package.

dotnet add package Dango.BlogUtils

After running the command, you can check if it was downloaded successfully by accessing the code of the .csproj file, which will have the following content:

Then, open the Program class and replace the existing code with the following:

using Dango.BlogUtils;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapPost("/slug", (SlugRequest request) =>
{
    var slug = SlugGen.GenerateSlug(request.Text);
    return Results.Ok(new { slug });
});

app.Run();

public record SlugRequest(string Text);

Note that, here, we created an endpoint that receives any text and uses the GenerateSlug() method from the NuGet package and returns the generated slug.

đź§Ş Testing the Application

Now let’s test if the package implementation and its usage are working. To do this, run the application (dotnet run), then make a request to the endpoint localhost:PORT/slug, passing any text in the body of the request as in the example below:

{
   "text": "Writing Clean Code in ASP.NET Core"
}

Then you will get the text transformed into a slug as a return:

{
    "slug": "writing-clean-code-in-aspnet-core"
}

This way, we have a functional application consuming the NuGet package created and published on nuget.org.

đź’ˇ Conclusion and Final Thoughts

NuGet packages allow companies and individual developers to share their ideas through reusable components, accelerating the development of web applications.

Consider a common task like deserializing JSON data, which is common in modern backend systems. Without NuGet, you would have to implement this functionality manually every time you need it.

While there are alternatives, such as using .dll files, none offer the same level of efficiency, convenience and integration as NuGet. With thousands of readily available packages and ongoing support in development environments like Visual Studio, NuGet greatly simplifies dependency management and promotes best practices in software development.

In this post, we created a NuGet package from scratch and saw how to publish it to nuget.org. Then we created a web API, added the package and tested the slug generation functionality.

I hope this post helped you understand how NuGet packages work and how to leverage these features to create and publish your own package.


About the Author

Assis Zang

Assis Zang is a software developer from Brazil, developing in the .NET platform since 2017. In his free time, he enjoys playing video games and reading good books. You can follow him at: LinkedIn and Github.

Related Posts