5 things your Umbraco package source needs
Tags: dotnet, umbraco, webdev, programming
Published: 2023-03-07 09:00:00

One of the major features of Umbraco is the rich package marketplace. At the time of writing, Umbraco has more than 1000 different packages available to customize your experience. If you're developing or maintaining a package, you'll want to ensure that it is of high quality and easy to work on. In this post I'll briefly highlight some tricks and features that will improve the developer experience of your packages.

## 1: [Directory.Build.Props](https://learn.microsoft.com/en-us/visualstudio/msbuild/customize-your-build?view=vs-2022)
If you have a decently sized solution, then you'll know that it can be painful to maintain your **dependencies** and **configurations** in each project. Updating a dependency in one project often means that you'll also update it all the others. _With a file named Directory.Build.Props, you can share project configurations between multiple projects._ Some of the configurations that I place in this file are:

- **Target framework**: It's convenient to have one place to specify which target framework my solution supports. Updating the framework version is much easier as well, as I only need to update the target framework in one place. [The DRY principle](https://www.digitalocean.com/community/tutorials/what-is-dry-development) comes to mind.
- **Static code analyzers**: I use several different analyzers and I just want them to work on all my source code. I put them in one place, so that I don't have to worry about the dependencies when introducing new projects in the solution or when moving projects around.
- **Common NuGet properties**: Especially logos, readmes and copyright statements are things that are the same in every project in the solution. I place them in one single file and they get applied to all the NuGet packages that I generate.

To get started with this file, all you need to do is create the file in an ancestor folder of the projects for which you want to share the properties. Once it's there, Visual Studio or the dotnet CLI will automatically pick it up and use it. You can then start moving the properties from your projects into this file. You can see [an example of the Directory.Build.Props file on my URL Tracker package](https://github.com/Infocaster/UrlTracker/blob/v10/develop/src/Directory.Build.props).

## 2: [Source Link](https://github.com/dotnet/sourcelink)
Especially if your package is open source, Source Link is a must-have for any serious package developer. _Source Link provides first-class source **debugging** experiences for binaries_. That means that consumers of your NuGet package can step into the **source code** of your package in their application without having to download your repository.

| 💡 You can also use this on private packages |
|-----------------------------------------|
| Source Link relies on the source of the package being available to the consumer. Your source can be closed as long as it is available to the developers who use your package. |

Implementing source link is almost as easy as installing a package. You simply reference the Source Link package that supports the host of your repository, set some configurations in your project or Directory.Build.Props file and enjoy. A working example can be found in [my ETag package](https://github.com/Infocaster/ETag/blob/v11/develop/src/Directory.Build.props) or in [the URL Tracker package](https://github.com/Infocaster/UrlTracker/blob/v10/develop/src/Directory.Build.props).

If you've done it correctly, NuGet will give your package some nice green icons of approval 🎉:

![Green icons show that a NuGet package has Source Link enabled](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ov7c1wbo9dfcdxs5tjg.png)

| ⚠️ Multiple remotes |
|---------|
| Source Link struggles with multiple remotes. You don't need Source Link when debugging your package locally anyway, so I recommend making the source link package reference conditional for **release builds**. When you make a release build in a pipeline or locally, make sure that the remote upon which the Source Link is based is the one named **origin** |

## 3: [AsyncFixer](https://www.nuget.org/packages/AsyncFixer) (and other static code analyzers)
If you're doing a lot of work in C#, you may benefit from working async. When done well, it can improve your package's **performance**. When done improperly however, it may lead to **deadlocks** and other problems that are difficult to fix. _AsyncFixer is a static code analyzer that gives you a warning when you're using async code improperly_. Using this analyzer, I've been able to prevent several difficult issues and I've been able to optimize my async methods. I often use this package in combination with [Microsoft.VisualStudio.Threading.Analyzers](https://www.nuget.org/packages/Microsoft.VisualStudio.Threading.Analyzers). Static code analyzers can prevent common security issues, enforce a code style and more, so it's definitely worth your time to check out what is available.

## 4: [Razor class library](https://learn.microsoft.com/en-us/aspnet/core/razor-pages/ui-class?view=aspnetcore-7.0&tabs=visual-studio)
A razor class library is like a normal class library, but with extra's. The big benefit of razor class libraries for Umbraco package developers is that _they can be shipped with **static assets** built-in to them_. Razor class libraries make many things easier:

- You no longer need a **targets file** to copy your static assets to the destination folder.
- You no longer need to explicitly include your static assets in your project, just place them inside **wwwroot**.
- While debugging, the static assets are directly served from the wwwroot folder in your library. This means that you can update the static assets without having to restart your application.
- You're less likely to have issues with caching of static assets or with remains of static assets after a deployment.

Razor class libraries make your development experience more straightforward and are therefore a feature that is definitely worth considering when building your package. See how you can [transform your package to use razor class libraries with this blog post](https://dev.to/kevinjump/umbraco-10-razor-class-library-packages-pt1-3nfa). You can also check out an example of a razor class library in [the URL Tracker package](https://github.com/Infocaster/UrlTracker/tree/v10/develop/src/UrlTracker.Backoffice.UI).

## 5: A frontend building framework (just any)
A controversial topic on this blogging platform for sure. I'm personally a fan of frontend building frameworks, even for packages. If your package is really just a single file of javascript, then don't bother, but if it starts to grow beyond that, you may benefit from it. I personally use **Webpack** for my projects and I use **typescript** (even more controversial here 😱). I gain a few things from this:

- I'm a .NET developer, I only know the frontend basics, so with typescript I can work in a way that is more familiar to me.
- My build output is a single javascript file, so I don't struggle with leftovers from previous package versions.
- I can use **npm packages**.
- I can use **unit tests** and **integration tests**.

I can say with certainty that I feel more confident with the introduction of a frontend build framework. If you want to see an example of an Umbraco package that uses Webpack, Typescript and Scss, check out this package for [Umbraco passwordless logins](https://github.com/Fjellvang/Our.Umbraco.Passless) or my [URL Tracker package](https://github.com/Infocaster/UrlTracker).

## Bonus: Managing tags and release notes
This is a bonus, because it's not finished, it's not refined, it's merely a proof of concept, but it has been working for me. I don't like managing release notes and I haven't been able to find a proper solution for it yet.
I created a visual studio plugin that helps me write release notes. What it does:

1. It asks for a version
2. It asks for new features, bugfixes and other changes
3. It suggests a title for the release that you can change if you don't like it.
4. It generates release notes, applies them to any .csproj file with the release notes tag.
5. It commits.
6. It creates a new tag named after the version with the release notes as the description.

![Example image of the GitChangelog UI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2nl2upvn2ozuy5z2x97j.png)

It's called [GitChangelog](https://github.com/D-Inventor/GitChangelog). I'm not going to release it, because I don't intend to maintain it. If you want to mess around with it, you can download the source and build the project yourself. Do with it what you want.

## Conclusion
There are many tools and features out there to make your Umbraco package development experience better. They can help with performance, security, maintainability and more! Now it's up to you to find the tools that are right for you. Which of these did you already know about? What other features or tools are a must-have for your package source? Let me know in a comment!

For now I'll say: Thanks for reading and I hope to see you in my next blog! 😊