8-Week Microsoft Teams AppDev Accelerator Program
Limited seats available! - Start date: Wednesday, April 16, 2025
Join Today & Save $1,000
articles

Fix the "can't find custom rule directory: tslint-microsoft-contrib" error in SPFx projects

Learn how to resolve the error: "[tslint] Failed to load ../tslint.json: Could not find custom rule directory: tslint-microsoft-contrib"

Fix the "can't find custom rule directory: tslint-microsoft-contrib" error in SPFx projects
by Andrew Connell

Last updated March 13, 2025
5 minutes read

Share this

Focus Mode

  • What’s the problem?
  • TL;DR
  • Unpacking the issue
  • Parting thoughts
  • Feedback & questions

Recently, when I was rebuilding all the projects in my Mastering the SharePoint Framework course to the latest version of the SharePoint Framework (SPFx) v1.12.1, I kept running into a random error. It didn’t happen all the time which made it not just annoying, but a pain trying to figure out the root cause.

Error - [tslint] Failed to load tslint.json: Could not find custom rule directory: tslint-microsoft-contrib

Error - [tslint] Failed to load tslint.json: Could not find custom rule directory: tslint-microsoft-contrib

It appears it’s just a random oddity that happens on occasion without a good explanation as to why. But the good news is that it’s easily fixed. In this post, I’ll explain the problem as well as how to fix it.

What’s the problem?

Occasionally you might get the following error when creating a new SPFx project or installing the dependencies of a project you collected. This shows up after you’ve installed all npm package dependencies and run your first build:

Error - [tslint] Failed to load {{project-path}}/tslint.json:
Could not find custom rule directory: tslint-microsoft-contrib

TL;DR

No time to read on about what’s going on and just want the fix? No worries… just install a missing npm package as a dev dependency and rebuild the project:

npm install tslint-microsoft-contrib --save-dev --save-exact

Unpacking the issue

Let’s take a look at what’s going on here.

The SharePoint Framework is still using TSLint, an extensible linter for TypeScript, even though it’s been deprecated for nearly 2.5 years. In addition to the default rules, Microsoft created some of their own custom rules. For instance, the no-cookies rule keeps developers from using the document.cookie API. These rules are defined in the npm package tslint-microsoft-contrib.

In default SPFx projects, Microsoft defines TSLint rules they believe every project should follow. This is done by adding the tslint.json file to your projects.

TSLint rules shouldn’t be included by default to new SPFx projects

Personally I disagree with the inclusion of this file… who are they to tell me how to code or what my company’s coding standards should be?

I tried, way back in July 2017 (see: sharepoint/sp-dev-docs#653) in the early days of SPFx, to get them to stop including this file, but as you can see from the discussion in that issue, I failed.

At least there’s a way to disable TSLint, but that means your workflow is always: create project > edit project to disable tslint.

If you take a look at the tslint.json file, you’ll see it extends the rules included with TSLint by referencing SharePoint-specific TSLint rules. These are found in the @microsoft/sp-tslint-rules npm package:

{
  "extends": "./node_modules/@microsoft/sp-tslint-rules/base-tslint.json",
  "rules": { .. }
}

Let’s follow the breadcrumbs…

Locate and open the base-tslint.json file referenced in our project’s tslint.json file. Notice it has a single property defining the Microsoft custom rules directory… it’s pointing to that npm package tslint-microsoft-contrib!

{
  "$schema": "http://json.schemastore.org/tslint",
  "rulesDirectory": ["tslint-microsoft-contrib", "./lib"]
}

Fantastic… now we can see how this is making it into the TSLint process.

But how is it getting into our project? That would be done by referencing it as a dependency or devDependency in a package’s package.json file. You’d logically expect to see this as a dependency of the @microsoft/sp-tslint-rules package… right? That’s the one that’s referencing it so it expects it to be there.

Now you’ll see where things start to break down. Take a look at the package.json file for the @microsoft/sp-tslint-rules:

{
  "name": "@microsoft/sp-tslint-rules",
  ..
  "dependencies": {
    "tslint": "~6.1.3",
    "tsutils": "~2.11.2"
  },
  "devDependencies": {
    "@microsoft/rush-stack-compiler-3.7": "0.6.38",
    "@ms/internal-heft-plugins": "0.3.1",
    "@ms/run-after-build-plugin": "0.1.0",
    "@ms/sp-internal-node-build-rig": "0.1.0",
    "@rushstack/heft": "0.24.1",
    "@rushstack/node-core-library": "3.35.2",
    "typescript": "~3.7.2"
  }
 ..
}

Notice anything missing? Yup… tslint-microsoft-contrib is a no-show.

But that doesn’t answer the question…

How does the npm package tslint-microsoft-contrib get into the project’s dependency tree?

Let’s dig further and open the package-lock.json file in the root of our project. That contains a manifest of the entire dependency tree. Search for the string tslint-microsoft-contrib. You’re looking for an instance of it in another package’s dependencies. In the project I’m playing around with, an SPFx v1.12.1 project that’s been updated to use TypeScript v3.9, I found this:

{
  ..
  "packages": { .. },
  "dependencies": {
    ..
    "node_modules/@microsoft/rush-stack-compiler-3.9": {
      "version": "0.4.47",
      ..
      "dependencies": {
        ..
        "tslint": "~5.20.1",
        "tslint-microsoft-contrib": "~6.2.0",
        "typescript": "~3.9.7"
      }
    }
  }
}

There it is… it’s a dependency on the npm package @microsoft/rush-stack-compiler-3.9.

So now we know how it’s getting installed on our project dependency tree. That doesn’t explain why it’s not getting installed at times and triggering the error I mentioned in the introduction of this post… we’ll just chalk that up to some weird circumstance.

Parting thoughts

Still… exposes something that’s a bit disappointing.

It’s a generally accepted practice that if you need something, you specify it as a dependency. Clearly the npm package @microsoft/sp-tslint-rules needs it, so why isn’t it listed as a dependency?

“Oh, it doesn’t matter because something it depends on needs it.”

While true, what would happen if the downstream packages decided they didn’t want to include it? It’s not their responsibility to find everyone who’s consuming them to say “hey, if you expected this, you should go install it yourself.”

From my point of view, the @microsoft/sp-tslint-rules should have the tslint-microsoft-contrib package listed as a dependency.

Andrew Connell, Microsoft MVP, Full-Stack Developer & Chief Course Artisan - Voitanos LLC.
author
Andrew Connell

Microsoft MVP, Full-Stack Developer & Chief Course Artisan - Voitanos LLC.

Andrew Connell is a full stack developer who focuses on Microsoft Azure & Microsoft 365. He’s a 20+ year recipient of Microsoft’s MVP award and has helped thousands of developers through the various courses he’s authored & taught. Whether it’s an introduction to the entire ecosystem, or a deep dive into a specific software, his resources, tools, and support help web developers become experts in the Microsoft 365 ecosystem, so they can become irreplaceable in their organization.

Feedback & Questions

newsletter

Join 10,000+ developers for news & insights

No clickbait · 100% free · Unsubscribe anytime.

Subscribe to Andrew's newsletter for insights & stay on top of the latest news in the Microsoft 365 Space!
blurry dot in brand primary color
found this article helpful?

You'll love these!

hTWOo: A Microsoft Fluent Design pure HTML & CSS Implementation

hTWOo: A Microsoft Fluent Design pure HTML & CSS Implementation

April 27, 2021

Read now

Join me at the Microsoft 365 Collaboration Conference - learn the SharePoint Framework in my half-day workshop

Join me at the Microsoft 365 Collaboration Conference - learn the SharePoint Framework in my half-day workshop

November 18, 2020

Read now

bi-weekly newsletter

Join 10,000+ Microsoft 365 full-stack web developers for news, insights & resources. 100% free.

Subscribe to Andrew's newsletter for insights & stay on top of the latest news in the Microsoft 365 ecosystem!

No clickbait · 100% free · Unsubscribe anytime.

Subscribe to Andrew's newsletter for insights & stay on top of the latest news in the Microsoft 365 Space!