5 Custom Linter Rules to Turbocharge Your Team's Productivity

Linters such TSLint and pyLint can be a great way to enforce standards on your team’s codebase; making your code more cohesive and easier to understand. Here are some helpful coding standards that you can impose using custom linting rules to elevate your team's output.

1. Something to think about

Ending a sentence with a preposition is a huge grammatical no-no. To keep your code grammatically correct, forbid comments that end with a preposition.

//Refactor later; this is the best hack I could think of.

❌ Invalid

It's very important to rigidly follow established grammatical rules. This comment is confusing and unprofessional.

//Refactor later; this is the best hack of which I could think.

✅ Correct

With just a few tweaks, you can change a garbled sentence into a comment that "just sounds right." Other team members will appreciate your professionalism and rigorous adherence to the rules prescribed by grammar.

2. Strong Password Policy

Preventing cyberattacks are everyone's responsibility. When accessing outside resources in code, it's good to make sure that your team takes security seriously. Make sure that your resources have an added layer of security by ensuring strong password policies when storing secrets in code.

This goes double for code committed to public repositories. Put your best foot forward and show how security minded your team is by only committing plaintext passwords that follow strict policies.

var username = "admin";
// Password with common words, no numbers,
// and no special characters!
var password = "seven-less-abroad-truly";

internalAccountingAPI.login(username, password);

❌ Insecure Password

In this example, you can see that the developer committed code with an insecure password. The password is four random common words, containing no capital letters, no numbers, no special characters, and it is longer than the standard 8 characters. Using such a weak password makes your internal accounting API vulnerable.

var username = "admin";
// Common words are obfuscated, length is 
// between 8-12 characters, and password 
// includes a number and special characters
var password = "P@ssword1!";

internalAccountingAPI.login(username, password);

✅ Rock Solid

Now this is a password you can confidently commit to your shared (or public!) repo. It obfuscates common words, contains special characters, capital letters, a number, and is the correct length. The accounting team will thank you for keeping their API completely secure.

3. Oxford Parentheses

Although functionally equivalent, exposed conditionals can be confusing. Add a rule that each conditional must be in its own parenthetical to reduce confusion.

if (a + b > 100 && a + b < 100 && isConnected == true)


These logical comparisons are a mess to read! Without proper parentheses, it's impossible to know which statements will be evaluated first. Some compilers may evaluate 100 && isConnected first and cause undefined behavior.

if ((a + b > 100) && (a + b < 100) && (isConnected == true))

✅ Perfect

The added parentheses force the compiler to evaluate your conditionals in the correct order. I call this Oxford Parentheses; named after the Oxford Comma in english, which is the best way to list things out.

4. Radical Accountability

It's common for developers to add a //TODO comment when something they're working on needs to be updated later. Make sure they hold themselves accountable by forcing such comments to include a due date, and make sure that due date is in the future.

//TODO: Fix this hacky code


This comment is unhelpful because it just defers the activity to a nebulous later date. It's impossible to track and even harder to evaluate this developer's productivity.

//TODO (Due: 20260402T015229Z) Fix this hacky code

✅ Accountable.

This is great because it holds the developer accountable to their date. If you couple this rule with a post-commit hook that automatically adds a user story to your task management system, you can correctly track this work. Be sure to use the correct ISO-8601 date/time format and industry standard UTC to increase readability.

5. Everyone Chimes In

Exceptions are a valuable debugging and flow control mechanism, but it can be hard to pinpoint exactly where an exception originated. Make sure your team maintains an accurate trail of breadcrumbs by mandating that all exceptions must be caught and re-thrown in each method they pass through.

  let resource = null;
  try {
    resource = getResource(); // Acquire the resource
    // Do stuff with resource
  } finally {
    resource?.close(); // Ensure the resource is closed, assuming it has a close method

❌ Misses Lots of Exceptions

getResource() above could throw all sorts of exceptions without this code knowing. You can't properly control the flow of your program without catching exceptions.

  let resource = null;
  try {
    resource = getResource(); // Acquire the resource
    // Directly use the resource in a one-liner operation
  } catch (error) {
    throw new Error("Error encountered.");
  } finally {
    resource?.close(); // Ensure the resource is closed, assuming it has a close method

✅ Catches Everything!

This is the proper use of exceptions. You wouldn't want highly technical error messages and ugly stack traces to bubble up to other methods; it's best to provide the calling methods a clean exception. Bonus points for including helpful status codes in your exception messages.