The NuGet packages we use to build elmah.io revisited

Four years ago, I wrote the blog post The NuGet packages we use to build elmah.io. Since then, we have made several changes to our tech stack as well as upgraded to recent versions of .NET. For this post, I'll update you on the packages we use as of writing this post. I hope you will find some inspiration in seeing how a system like elmah.io is built.

The NuGet packages we use to build elmah.io revisited

While many new packages have been added since the last post, I will split this post into two parts. In the first part, I will list and describe the packages that have been added as new or replacing existing ones. In the second part, I will list the packages we still use. For details about these packages, check out the description in the previous post. If you would like to know more about any of the packages, let me know and I'll consider writing a post specific about a package (if not already there).

New and changed packages

AI packages AI packages

Since writing the last post, a range of new AI-based features have been added to elmah.io. Back then, the main use of AI was for spike detection based on the Microsoft.ML package. Since then we have added integration with ChatGPT which uses the Azure.AI.OpenAI package. Recently, our new chatbot Bugster was introduced, built on the Microsoft.SemanticKernel package.

NuGet: https://www.nuget.org/packages/Microsoft.ML/

NuGet: https://www.nuget.org/packages/Azure.AI.OpenAI

NuGet: https://www.nuget.org/packages/Microsoft.SemanticKernel

Azure.* Azure.*

We have moved entirely from the old Microsoft.Azure. packages to the new generation prefixed simply with Azure.*. The main packages here are Azure.Storage.Blobs for communicating with Azure Blob Storage and Azure.Messaging.ServiceBus for communicating with Azure Service Bus. Since this is the third re-write or so, I really hope that Microsoft will settle on this package for at least a few years 😅

NuGet: https://www.nuget.org/packages/Azure.Storage.Blobs

NuGet: https://www.nuget.org/packages/Azure.Messaging.ServiceBus

HtmlAgilityPack HtmlAgilityPack

I'm guessing this is a package many of you already heard about or maybe even use today. HtmlAgilityPack is a great option for parsing and querying HTML documents in C#. We use HtmlAgilityPack heavily in our Uptime Monitoring feature to implement features like our Canonical checker.

NuGet: https://www.nuget.org/packages/HtmlAgilityPack

IPNetwork2 IPNetwork2

IPNetwork2 is one of those smaller packages that handles one specific thing very well. In this case, it's dealing with IP addresses. While .NET has built-in support for parsing IP addresses in the System.Net.IPAddress class, it does not support the CIDR notation. We use that for implementing the ignore filter for a range of IP addresses by specifying an IP range like this: 192.168.0.0/24. IPNetwork2 add methods for doing exactly that.

NuGet: https://www.nuget.org/packages/IPNetwork2

Newtonsoft.Json and System.Text.Json Newtonsoft.Json and System.Text.Json

The whole world is in the process of switching from Newtonsoft.Json to System.Text.Json and so are we. For our API we still use Newtonsoft.Json since our client is generated using NSwag, which still depends on the package. In all other instances where we need to generate or parse JSON, we now use System.Text.Json.

NuGet: https://www.nuget.org/packages/Newtonsoft.Json/

NSubstitute NSubstitute

I know that I already mentioned this in the previous post. But since writing that, all of our code has been migrated from Moq to NSubstitute. While Moq is a great framework we decided to switch to NSubstitute simply because of an (IMO) simpler API. This happened way before the security issue with Moq that you may have heard about. Since our switch started before and didn't have anything to do with that incident, I won't touch upon this further. I still think Moq is a perfectly fine mocking framework.

NuGet: https://www.nuget.org/packages/NSubstitute

Rfc2253 Rfc2253

Much like the IPNetwork2 package, Rfc2253 is used to parse a string and convert it to something else. As part of elmah.io Uptime Monitoring, we store the certificate when the user enables the SSL certificate expiration check. To present the certificate information in a more pleasing form on the UI, we use the Rfc2253 package to convert it into a strongly typed object.

NuGet: https://www.nuget.org/packages/Rfc2253

SourceMapTools SourceMapTools

Back when we introduced server-side source map support on elmah.io, we needed a package to help de-minifying JavaScript stack traces on the server. This works by the user uploading a source map through the elmah.io API, and we will then de-minify any minified stack trace we receive using the SourceMapTools package. Running JavaScript-like features on a .NET backend is easy with packages like this.

NuGet: https://www.nuget.org/packages/SourceMapTools

TimeZoneConverter TimeZoneConverter

Getting the timezone on users right is important for a range of reasons on a system like elmah.io. When creating a new account, the user needs to pick their timezone. To map the current IANA timezone from the browser to a Windows timezone, we use the excellent TimeZoneConverter package.

NuGet: https://www.nuget.org/packages/TimeZoneConverter

Walter.Vat Walter.Vat

People not running a business are often surprised when I tell them of all of the smaller, administrative tasks needed to run a system like elmah.io. One of many is being able (and required) to validate European VAT numbers regularly. If you think this sounds boring, you are 100% right. Luckily, a task like this can be solved by NuGet packages like Walter.Vat.

NuGet: https://www.nuget.org/packages/Walter.Vat

Still using

AspNetCoreRateLimit: Used for defining rate limits in ASP.NET Core.

AWSSDK.SimpleEmail: Used for sending emails through AWS.

BundlerMinifier: Used to bundle js and CSS files.

Elmah.Io.*: Used for monitoring elmah.io.

GoogleAuthenticator: Implements 2FA on app.elmah.io.

Intercom.Dotnet.Client: Used for enriching data in Intercom.

IP2Location.IPGeolocation: Used for extracting info about IPs.

Microsoft.Extensions.Logging: Used for logging.

NEST: Client for communicating with Elasticsearch, our main data store.

NReco.PdfGenerator.LT: A client based on wkhtmltopdf to generate PDF files.

NUnit: The well-known unit testing framework.

Polly: Retries, Circuit Breaker, etc.

PwnedPasswords.Client: Used to detect when someone uses pwned passwords.

Spectre.Console: Creates beautiful-looking CLIs.

Stripe.Net: Handles all of the payments on elmah.io.

Swashbuckle.AspNetCore: Generates the Swagger API and UI.

System.CommandLine: Parse command line parameters for CLIs.

UAParser: Extract information from a UserAgent string.


That's a quick list of some of the essential NuGet packages we use. If there's a general interest in going into details with each package, let me know and I'll think about a format to implement this with.

elmah.io: Error logging and Uptime Monitoring for your web apps

This blog post is brought to you by elmah.io. elmah.io is error logging, uptime monitoring, deployment tracking, and service heartbeats for your .NET and JavaScript applications. Stop relying on your users to notify you when something is wrong or dig through hundreds of megabytes of log files spread across servers. With elmah.io, we store all of your log messages, notify you through popular channels like email, Slack, and Microsoft Teams, and help you fix errors fast.

See how we can help you monitor your website for crashes Monitor your website