ChatGPT: The ESLint Rule Maker

Mar 02, 2023

By Paden Portillo, Principal Software Engineer, Brinqa

I’m old enough to remember when IBM’s Watson, a question-answering computer system, beat champions Ken Kennings and Brad Rutter on “Jeopardy!”. That event, although incredible and with the clout of Alex Trebek to back it, did not even come close to the amount of hype we are seeing today with AI. Even as I’m finalizing this blog post, Google and other competitors are entering the market (ready or not).

In the words of the French writer Victor Hugo: “Nothing is more powerful than an idea whose time has come.”

There are many articles delving into the sophistication and downfalls of ChatGPT. I won’t reexamine these topics here. As a developer and manager of a team, I am focused on how this can better the people on my team and their processes. In that vein, I’d like to show how Brinqa’s UI team has been putting ChatGPT to the test with ESLint.

ESLint and Creating Rules

Who doesn’t like a linter informing you that your code is subpar? In all honesty, ESLint is a great way to put guardrails around developers. At Brinqa, we rely on ESLint to ensure all code that is checked in follows our conventions and styling.

There’s a slew of ESLint rules you can use out of the box that covers 90% of your conventions. It’s actually quite impressive. You have two choices for that last 10% of coverage: One, you can add documentation to a README and spread that knowledge amongst your team when commenting on pull requests, “Hey! You didn’t follow our 142nd coding convention buried in a README five folders deep in the repo!” Or, two, you can create an ESLint rule yourself.

Creating ESLint rules is quite the journey. First, you must learn the abstract syntax tree, or AST, terminology for Javascript/Typescript. Then use that syntax to target the coding convention you are enforcing. Once that fun is done, you test and fine-tune that rule, ensuring it’s not over-targeting or missing use cases.

As for me, I’d love to get in the minutia of AST and spend countless days making the perfect rule. However, as a developer, I always ask the question: How can this new technology make my life better?

Enter ChatGPT

How can we use ChatGPT along with ESLint? Could we ask ChatGPT to create a rule for a convention not supported in our current ESLint ecosystem?

We currently use a little-known framework you may have heard of called Angular. In it, you can propagate data back and forth using class fields imbued with Input and Output decorators. Pretty slick.

However, if a referenced type, such as an object or function, is passed from one component to another — it can and will, be mutated. This can result in many unintentional side effects. You do not want some grandchild component changing some data unbeknownst to its ancestors. Let’s see what ChatGPT comes up with:

ChatGPT Prompt: Create an ESLint rule that will warn a developer if a class field with the decorator “Input” is being mutated. It should also warn if any nested properties within that class field are being mutated.

Output: The rule checks for two different cases of mutation:

  1. When assigning a value to the class field, use the syntax field = value.

  2. When the class field is being destructured, and a value is being assigned to one of its nested properties, using the syntax const { nestedProp: nestedProp = value } = field.

Quite impressive. First, maintaining AST is much easier on the eyes once you have some pre-written code, especially when comments are added out of the box, which is more than I can say for some developers (myself included at times). However, there seems to be a missing use case I was hoping it would pick up on: I do not want nested properties to be mutated as well.

ChatGPT Prompt: Extend this rule to warn of mutations that look like `this.field.nestedProperty = value`

Output: Sure, here’s an updated version of the rule that also checks for mutations of nested properties within a class field:

In this updated version, the rule now checks for an additional case of mutation:

  1. When assigning a value to the nested property of a class field, use the syntax this.field.nestedProperty = value.

There it is! It extended the rule and added my third use case. As I went to test this a bit, I realized this is an old rule format for ESLint. The final task will be to get ChatGPT to update the rule format. Let’s see how it does:

ChatGPT Prompt: Update the rule above to be compatible with ESLint 3.0

Output: This rule is now compatible with ESLint 3.0. The rule structure has been updated to follow the current guidelines and conventions of ESLint, and it uses the new context object to access the rule’s metadata and report violations. Here’s an updated version of the rule that’s compatible with ESLint 3.0:

In this updated version, the rule now checks for an additional case of mutation:

Now we have a fully functional ESLint rule that is compatible with the latest rule format! From start to finish, it took all of 5 minutes to write these prompts and get the responses. Once again, this probably requires some fine-tuning, but 5 minutes of prompt engineering got us 95% of the way there.

Brinqa UI is now powered by AI!

Since we used AI to generate a linter rule, we can now market ourselves as “AI-Powered.” That’s how it works, right? Well, probably not, but in any case, it’s been exciting to see how AI can be added to a developer’s tool belt.

Related resources