Nuget has become such a valuable part of the .Net ecosystem it's any wonder how we got the job done with 3rd party packages without it. When working on projects in a team many developers turn on Nuget Package Restore to save them having to check their packages into Source Control. This allows them to have their packages download whenever a new developer goes to build. It’s also quite popular with project teams that have Continuous Integration setup. I recommend against Nuget Package Restore, as I’m simply not a fan.
When Nuget was first released the majority developers in .Net land rejoiced. No longer would we have to download, checkout, test and build third party open source libraries. We also didn’t have to worry about keeping them up to date. More importantly it also put a number of .Net developer’s minds at ease, as the next time they struck up conversation with someone they knew from the land of Ruby on Rails they finally had a response when the topic turned to discussions about their mystical "Gems"!
Nuget Package Restore soon followed Nuget and allowed us to easily have our packages downloaded on every build without having to store your package binaries in your source control. This makes it easier to share projects with fellow developers as you only need to send your code. With Nuget Package Restore your build server can also happily "fill in the blanks" for any packages that it was missing every time it went to build a new release for you.
I argue that not all of this glittery stuff that comes with Nuget Package Restore is gold, and I actually think it teaches bad habits and causes any number of issues that didn’t exist before it graced our developer bat belts. As I haven’t heard anyone raise much comment in line with my line of thinking I thought I'd vent the only way a guy from the internet like me can. A whingey Blog post.
The first and simplest reason I’m not a fan of Nuget Package Restore is how it affects build times in teams where you’re using Continuous Integration (i.e really any team that understands the value that CI brings; if you haven’t taken a look, now is the time). When using a build server, large projects take time to finish building. Your build server has to download your source, build your binaries, run your unit tests, any integration tests and optionally deploy your application. Every second counts.
A large solution may take many minutes to finish building and testing. If your build server has to download packages on every build you’re simply stealing valuable time away from yourself, as you are just extending the time it takes to have your unit tests fail, and therefore give you less time to troubleshoot any bugs you’ve introduced from your last check in. By removing the need to download your Nuget Packages you instantly speed up your build to the breakneck speed of…
Wait for it…
The speed you had in the dark old ages you checked in your binaries (shock horror!).
The only time adding binaries to your source control doesn’t speed you up dramatically is in certain situations where you are using DVCS like as Git or Mercurial. Over time it may slow down your clones on large repositories. But like most things, this is just an excuse to not dig deeper. There are ways to work around these issues by using techniques such as using Git submodules to store binaries in another repo.
This is actually my number one reason for steering clear of Nuget Package Restore. If Nuget.org is down, your builds are down.
“… As if that’ll ever happen, the gains are worth the risk…”
But my opinion is you’d be wrong. Case in point is the fact that there has been 2 periods where Nuget.org has been down for a few hours each just this month alone (January 2012):
and it gets worse:
So if I interpret this for you: If you share your project with anyone or try and do an automated build on your build server and Nuget.org is down, you’re fresh out of luck!
Peter Newhook summarises this well:
This isn’t a reflection of Nuget.org – we don’t pay for the service. After I experienced this for the first time, I realised that using Nuget.org as a build dependency wasn’t something I could put my team or clients up against. And the solution was simple: I checked in my Nuget packages, avoided Nuget Package Restore and never thought about it again.
Control Over Dependency Versioning
Another thing with Nuget Package Restore that I’m not the biggest fan of is the way it effects your ability to ensure your QA teams they don't need to take another look after a build.
When you’re working with a set of binaries on your local environment and then check your code in without the packages you were using, my gut feeling is that there is no absolute way of knowing that the very same binaries will be used by your team mates or the packages downloaded by your continuous integration environment. You are ceding control of this to the Nuget gods. If one day Nuget just happened to serve a different package to your team mate or build server bugs may be introduced. At this point you've unnecessarily introduced a roadblock.
Like my other complaints, this problem is one that’s easily avoided if you just check your packages in, and turn off Nuget package restore.
Ask yourself, what happens if the next time you open an old project and you no longer can download the package because it’s been removed from Nuget? Or if there is a technical difficulty at Nuget that stops you from getting it.
Laws of Continuous Integration
This brings me to my final and probably most passionate reason for wanting to avoid Nuget Package Restore: I feel that having your solution depend on remote dependencies breaks one of the elementary rules of Continuous Integration/Deployment and Source Control usage. To me this rule is one of the most important rules I try to live and die by as a developer:
“… Source control is number one in both configuration and logic storage. A new developer needs to be able to have everything in a state where they can load it up in 1 command, and deploy it with another…”
Living by this thinking dictates that what is in your source control is more than just your code. Your application is code, configurations, dependencies, and anything needed to build your application. I’ve heard some people even say that they suggest placing their IDE and any tooling they use in their source control. This kind of thinking definitely includes your packages. If a new team member can’t get the folder for your solution and be ready to roll, I get the feeling I’ve divided by zero with the universe. This may just be a personal thing for me, but it feels pretty sacrilegious to do it any other way.
Rewind the Clock, and Check-in
If you’re like me and consider any of the above to not sit right with you, and any of the annoyances or inconveniences that using Nuget package Restore can bring along for the ride when you use it doesn’t feel like it’s worth it, then I’d suggest you follow my lead and avoid using Nuget Package Restore in a production environment. Check in your packages, it’s that easy.
Update 3rd February 2013.
I’ve received a fair few messages on Twitter about this post. So I thought I’d take the time to clarify a few things:
- This post is about Nuget Package Restore – not Nuget.
I love Nuget, and have very little else to say about it; even though Nuget does go down from time to time, it’s acceptable. On the other hand, I strongly feel that you should be checking in your packages instead of having Nuget Package Restore download them on your build server or when new developers start using your project.
- I understand there are a few ways you can make the situation a little better. This doesn’t change my view.
You can install a package server locally. You could cache or backup your Nuget cache folder. None of these solve the biggest issue I have in that you don’t have everything your project needs to build included in Source Control.
- I mention that the speed on your build is important, and that Nuget Package Restore slows this down slightly. I didn’t back this up with data – If I wanted to make a big point out of it I should have. This wasn’t my main concern though. I mentioned you’d get faster builds if you check in your packages. This should be the case if you have 1 package, 10 packages, slow internet, fast internet etc – so I didn’t really feel the need to go into too much detail. If I have more time I will take the time to write about it soon.
- As with everything I blog about, this post is my opinion. You may feel differently about the topic. This is OK. It doesn’t mean that I’m saying that “If you use Nuget Package Restore, you’re an idiot”, but it does mean that I think you might either not be fully aware of what using Nuget Package Restore means for your project, or you do and are OK with it. Keep on!