Progressive Lint: How to continuously improve the codebase

TL;DR — How I stopped wasting my time breaking all the apps: I built a solution to improve the entire codebase during the development workflow. This post shows the usage, how to setup and start using progressive lint mechanism

Before we get started, this article is a continuation of a previous article that explains how to Build Scalable Code Style in a JavaScript Codebase. I truly recommend reading the first before continuing this one.


Have you ever broken any application trying to improve it? Or have you ever applied a new lint rule and spent a lot of time fixing the code?

I’ve been through both situations. Progressive Lint helped me to avoid those pitfalls moving forward.

So, in this post, we’re going to see:

  • The problems that we faced when we weren’t using a progressive approach
  • Real world use case at QuintoAndar
  • How to set up progressive lint

Let me tell you a story of how I broke some apps trying to make them better…

First of all, I’m known as “lint addicted” in my work at QuintoAndar, because I always get small details in code reviews and I really really like eslint. (As you can see, this is my second article about it 😅)

However, it’s impossible to predict all the rules before you start the project. This happens because some of them will be chosen later, or a new rule or pattern was decided later. There’re lots of reasons to update it later.

So, it’s necessary to do improvements when the project is already live. It’s like: Fixing the plane while flying it.

I wanted to fix while the project was live, but my mistake once — by once I mean a couple of times — was that I was trying to do this as a one time job.

Sometimes, I got a project that I've never worked on and applied eslint settings, from zero or only the new rules. Of course, It didn't end well.

I tried to take care. I ran the tests, ran the server locally, rendered some pages and called some endpoints. But still, some “planes” crashed.

After I successfully failed with some applications trying to make them better. I realized that it was costing more than I expected, so, it wasn’t being worth it.

It costed so much of my time! But, the worst part was that most of the time I needed to redo my work. Other developers were working on the same project, and time and time again I needed to rebase and resolve conflicts 🙄.

I understood that this approach wouldn’t scale. Plus, we have a Design System and specialized guild for Front-end, which means we’re usually working on new patterns and how to do things better.

There will always be more projects and more rules to apply!

Thus, I needed to find a way to do it progressively. That's what I did! For my surprise, it was simpler than I thought at first.

What’s the idea behind a progressive lint?

We just need to run the new rules in the modified files in the feature branch. This way, applying new lint rules is part of the workflow of each software engineer that’s working on this project.

Yes, even if the developer does a minor change in the file that contains something that violates the new rule, she/he is going to be forced to fix the entire file.

By the first look, it can sound bad because of the context switch or blocking the person to finish the task, but allow me to be cliché right now:

All software engineers working together on it in the normal workflow, makes us achieve more! It’s so much more scalable.

Do the other Software Engineers like it?

Now, you may say:

Ok, it worked, but.. does the software engineer like it?

Hmm, I answer:

It worked, but ‘like’… that’s another thing!

I’m kidding! 😛

Everytime that anybody sees some error of the progressive lint, we always get bored like “Oh, Do I really need to fix it?! 😒”. But the truth is most people complain and don’t like it at first, but none of them argue it is not worth it.

We know that it’s going to arrive the day that we fixed all code is up to this rule and a new one is going to come!

The results make us excited to do it and see the code quality always improving!

Our real current usage

We are still working and improving it, but we already did some pilots by now. And new rules are coming in which we’ll use the same approach too.

The pilot of progressive lint was to deprecate a component that we used to use. The name of it was Typo, and we needed to stop using it and start using a new one that was better aligned with the design system.

First, we tried to create a task force cross teams and treat as one time job, but as you can imagine that didn’t work. So, it was a good opportunity to create progressive lint and use it as a pilot. We created a new rule and put in the progressive mode.

What happened? It worked!

Every time we change a file that has an import of the deprecated component, we need to update it to use the new one! 😉

And we continue… We recently added another rule for file naming that is working. And coming soon: more rules about imports, components and best practices!

Therefore, my friendly advice is: If you’re not doing things using a progressive approach. You should start doing it and analyze the results!

So far we know the costs and benefits of the progressive approach. Let’s see now how you can do that for your project.

How do we do progressive lint?

First, we need to add another script inside our package.json to run the command of progressive lint.

The main difference is that we need to add the config file for the rules that are going to be applied. Like the script below.

After that, we need to create the referenced file that specifics all the rules/settings that you want to apply in a progressive way.

Then, we need just run the command with this script in the changed files. The best way we found so far was this:

This file should represent the CI file where we put the commands that should run. In this case, I'm putting a yml with the drone syntax, because we use drone at QuintoAndar, as you can see in this article.

So, in the first command, we just fetch the base branch in this case (master) after we get the changed files using GIT.

git diff --name-only origin/master 

The command gets all the names of the files that were changed compared with the base branch. To specify, we just want Javascript files, so we pass the result of the command above as input of the next command:

| grep '.js*$'

Last, but not least, we run the command of progressive lint that we did, passing only the changed files as params to eslint.

npm run lint:progressive $FILES_CHANGED

And that’s it…

With a few lines, we made progressive lint part of our workflow without pain, rework or breaking the app! And this can only be achieved with all software engineers working together ❤️


Join Us

If you like challenges and you want to work in a startup that is redesigning the entire experience of the rental process. Using technology and design as the core components. Look at our job opportunities on our career page, we’re always looking for talented and eager to learn people.


Tks for reading! I’m always open to receive feedback, recommendations or questions, feel free to contact me!!

LinkedIn: https://www.linkedin.com/in/pamepeixinho
Twitter: https://twitter.com/pamepeixinho
GitHub: https://github.com/pamepeixinho
Website: https://pamepeixinho.github.io

My last name is Fishie, I swim and code sometimes. “Sea” you later! 😉