Over a million developers have joined DZone.

Why I Use Paket Now

DZone's Guide to

Why I Use Paket Now

If you've used NuGet in the past for web development projects and had some issues, you're not alone. See why one dev switched to Paket over NuGet.

· Web Dev Zone ·
Free Resource

Access over 20 APIs and mobile SDKs, up to 250k transactions free with no credit card required

I never really had any major problems using the NuGet client. By reading their Twitter timeline, it seems I am the only one without problems. But depending on what dev process you like to use, there could be a problem. This is not really NuGet's fault, but this process makes the use of NuGet a little bit more complex than it should be.

As mentioned in previous posts, I really like to use Git Flow and a clear branching structure. I always have a production branch, which is the master. It contains the sources of the version which is currently in production.

In my projects I don't need to care about multiple version installed on multiple customer machines. Usually as a web developer, you only have one production version installed somewhere on a webserver.

I also have a next version branch, which is the develop branch. This contains the version we are currently working on. Besides this, we can have feature branches, hotfix branches, release branches, and so on. Read more about Git Flow in this pretty nice cheat sheet.

The master branch gets compiled in release mode and uses a semantic version like this: (breaking).(feature).(patch). The develop branch gets compiled in debug mode and has a version number that tells NuGet that it is a preview version: (breaking).(feature).(patch)-preview(build). Here, build is the build number generated by the build server.

The Actual Problem

We use this versioning, build, and release process for web projects and shared libraries. And with those shared libraries, it starts to get complicated using NuGet.

Some of the shared libraries are used in multiple solutions and shared via a private NuGet feed, which is a common way of doing things, I think.

Within the next version of a web project, we also use the next versions of the shared libraries to test them. In the current versions of the web projects, we use the current versions of the shared libraries. Makes some sense, right? If we do a new production release of a web project, we need to switch back to the production version of the shared libraries.

We do this because, in the solutions packages folder, NuGet creates package sub-folders containing the version number. And the project references the binaries from those folder. Changing the library versions needs to use the UI or to change the packages.config AND the project files, because the reference path contains the version information.

Maybe switching the versions back and forth doesn't really makes sense in the most cases, but this is the way I also try new versions of the libraries. In this special case, we have to maintain multiple ASP.NET applications, which uses multiple shared libraries, which are also dependent to different versions of external data sources. So a preview release of an application also goes to a preview environment with a preview version of a database, so it needs to use the preview versions of the needed libraries. While releasing new features, or hotfixes, it might happen that we need to do a release without updating the production environments and the production databases. So we need to switch the dependencies back to the latest production version of the libraries.

Paket Solves It

Paket, instead, only supports one package version per solution, which makes a lot more sense. This means Paket doesn't store the packages in a sub-folder with a version number in its name. Changing the package versions is easily done in the paket.dependencies file. The reference paths don't change in the project files and the projects immediately use the other versions, after I changed the version and restored the packages.

Paket is an alternative to the NuGet client, developed by the amazing F# community.

Paket Works Well

Fortunately, Paket works well with MSBuild and CAKE. Paket provides MSBuild targets to automatically restore packages before the build starts. Also, in CAKE, there is an add-in to restore Paket dependencies. Because I don't commit Paket to the repository I use the command line interface of Paket directly in CAKE:

.Does(() =>

.Does(() => {
var exitCode = StartProcess(".paket/paket.bootstrapper.exe");
Information("LoadPaket: Exit code: {0}", exitCode);

.Does(() =>
var file = "./SolutionInfo.cs";
var settings = new AssemblyInfoSettings {
Company = " YooApplications AG",
Copyright = string.Format("Copyright (c) YooApplications AG {0}", DateTime.Now.Year),
ComVisible = false,
Version = version,
FileVersion = version,
InformationalVersion = version + build
CreateAssemblyInfo(file, settings);

.Does(() => 
var exitCode = StartProcess(".paket/paket.exe", "install");
Information("PaketRestore: Exit code: {0}", exitCode);

// ... and so on


No process is 100% perfect, even this process is not. But it works pretty well in this case. We are able to do releases and hotfix very fast. The setup of a new project using this process is fast and easy as well.

The whole process of releasing a new version, starting with the command git flow release start ... to the deployed application on the web server doesn't take more than 15 minutes, depending on the size of the application and the number of tests to run on the build server.

I just realied, this post is not about .NET Core or ASP.NET Core. The problem I described only happens to classic projects and solutions that store the NuGet packages in the solutions packages folder.

Any questions? Do you wanna learn more about Git Flow, CAKE, and Continuous Deployment? Just drop me a comment.

#1 for location developers in quality, price and choice, switch to HERE.

web dev ,paket ,nuget

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}