Mea culpa - always install gulp-cli globally, not gulp

This is a story about a mea culpa. That’s me saying “I got it wrong and I want to fix it”, and while I’m not speaking for Microsoft on my blog, I believe I’m also speaking for them as well. For the longest time, SharePoint Framework (SPFx) developers were told to install gulp globally when setting up their development environment. However, that’s been wrong all along. You should have been installing the gulp-cli package globally (as the docs show), not gulp globally. To better understand why, keep reading.

Anmiated GIF

Photo by Annie Spratt on Unsplash

This is a story about a mea culpa. That’s me saying “I got it wrong and I want to fix it”, and while I’m not speaking for Microsoft on my blog, I believe I’m also speaking for them as well.

For the longest time, SharePoint Framework (SPFx) developers were told to install gulp globally when setting up their development environment. However, that’s been wrong all along. You should have been installing the gulp-cli package globally ( as the docs show ), not gulp globally.

To better understand why, keep reading.

TL;DR: always install gulp-cli globally, never install gulp globally

To best understanding why you should be installing gulp-cli globally and not gulp, you need to understand why there are two different packages. While not a complete story, it’s easiest to understand the transition from gulp v3 vs. gulp v4. But first, let’s look at how gulp is organized.

Gulp originally contained two things in a single package:

  • A JavaScript library that enabled you to use gulp from JavaScript code, such as your gulpfile.js or when creating custom task libraries; think of this like React. You don’t run React in your projects, rather your project uses the React library to implement your user experience.
  • A program, or a CLI, to access and run gulp from your console. This is what looks for your project’s gulpfile.js to load the tasks that you can run from the console or can list all the available tasks when you supply the --tasks command line argument.

Originally, the guidance was to install gulp both globally as well as locally within your project. This was fine when there was just one version of gulp because the CLI part of gulp could call and run the JavaScript library part of gulp. If all the projects on your dev environment used the same version of gulp, no problem!

But the team could see a point in the future where this might not be true - what if some projects were using one version of gulp while other projects used a different version. The gulp team decided to split these two things out into separate packages:

  • gulp-cli : separate stand-alone program (CLI) that enables you to run gulp from the console
  • gulp : the JavaScript library that you can use in your gulpfile.js (this package still had the CLI in it so it)

Most people didn’t take notice of this change, even though the v1 CLI was introduced in November 2015.

In fact, as a SPFx developer, as many readers of this site are, you might never have heard of the gulp-cli. You were told by Microsoft and others to just install gulp globally. Everything worked just fine because we were all using gulp v3 in our projects.

Gulp v3 ⇒ gulp v4

When Node.js v12 was released, the gulp team realized they had to make significant changes to gulp to support the new Node version. Ultimately they decided instead of adding complex modifications to gulp v3, the better approach would be to release a new major version that wasn’t backwards compatible.

So, they decided that gulp v3 would continue to work only up through Node.js v11 while the new version, gulp v4 would be supported on Node.js v12+.

But that doesn’t answer the why gulp-cli question. Correct… stay with me…

Conflicting gulp versions between global & local installations

gulp (the program) can only run gulp tasks that use the same matching library version.

So, if you install gulp v3 globally, you can only run tasks in projects that use the gulp v3 library.

Gulp v3 installed globally

Gulp v3 installed globally

When everything is v3, it works

Conversely, if you install gulp v4 globally, you can only run tasks in projects that use the gulp v4 library.

Gulp v4 installed globally

Gulp v4 installed globally

When everything is v4, it works

But what happens if you have differing versions? What you can’t do is run gulp tasks written with one library version, such as v3, but you’ve installed a different gulp version, such as gulp v4, globally.

Gulp installed globally with mixed project versions

Gulp installed globally with mixed project versions

When the version used in projects doesn’t match the globally installed version, bad things can happen…

SPFx developers may have already run into this. Starting with the SPFx v1.12.1 release, Microsoft updated new projects to use the gulp v4 library instead of the gulp v3 library. As such, in the release notes, they also instructed us to install gulp v4 globally.

That’s fine & our projects worked just fine, except when we tried to run gulp v3 against an older SPFx project. For instance, if you had a SPFx v1.11+ project on the same environment, you might run into an error. Then again, depending what the task was doing that you ran, you might not run into an error. But you might one day because running one major version of gulp against a mismatched project that uses a different major version is simply not supported; at some point it will break.

This is where the guidance from Microsoft’s SPFx docs was… well… misguided.

And I admit it… my guidance that I was telling developers was wrong too. In fact, I’m one of the maintainers of the SPFx developer docs and release notes for new versions. This got by me multiple times.

But when you’re wrong, you’re wrong & should admit it as part of making it right. That’s what I’m doing here.

Always install the gulp-cli globally, not gulp

As I mentioned previously, the way the gulp team addressed this issue was to release another package, the gulp-cli, that’s intended to be installed globally. Once you do that, you have the gulp program that’s version agnostic from the version of the gulp library you’re using within different projects on your environment.

Gulp CLI vs. gulp v3 and v3

Gulp CLI vs. gulp v3 and v3

The gulp-cli fixes this mis-matched version issue

Gulp, the JavaScript library, should be installed as a devDependency within your project if it’s using gulp tasks.

For SPFx developers, that’s taken care of for us when we scaffold new projects - the project contains the version of gulp it needs.

I’ve never had a problem running gulp globally - why does this matter?

Just because you haven’t had a problem doesn’t mean you won’t in the future. If you’re using gulp v3 globally, eventually you’ll have an issue. Gulp v3 isn’t supported on Node.js v12+ nor is it supported with gulp v4 projects.

While it may work, at some point in the future, it won’t.

I don’t work on SharePoint Framework projects - does this matter to me?

Yes… this isn’t a SharePoint Framework issue. This issue has nothing to do with SPFx.

This issue is entirely about running gulp tasks and the version of Node.js installed in your environment.

I’ve used SPFx as my example throughout this post, but only because that’s what a lot of people come to this site are looking for. If you’re just a Node.js developer who works on projects that use gulp, this applies 100% to you as well.

This is a story about a mea culpa. That’s me saying “I got it wrong and I want to fix it”, and while I’m not speaking for Microsoft on my blog, I believe I’m also speaking for them as well.

Andrew Connell
Developer & Chief Course Artisan, Voitanos LLC. | Microsoft MVP
Written by Andrew Connell

Andrew Connell is a web developer with a focus on Microsoft Azure & Microsoft 365. He’s received Microsoft’s MVP award every year since 2005 and has helped thousands of developers through the various courses he’s authored & taught. Andrew’s the founder of Voitanos and is dedicated to delivering industry-leading on-demand video training to professional developers. He lives with his wife & two kids in Florida.