How to build a linter
Build your own linter from scratch
You’ve probably already met the dreaded linter. If not, fear not, read this first: The dreaded Linter
Today, we’re taking this relationship to the next level. Instead of fearing the Linter, you’re going to build one! Let’s go!
First: What Isn’t a Linter?
A linter is not:
-
A compiler
-
A formatter
A linter analyzes code for:
-
Suspected errors
-
Bad patterns
-
Style violations
-
“Why did I write that?!” situations
Let’s Build One Then
To build a linter, you need three things:
-
Code to inspect
-
Rules to enforce
-
A system to yell at you when you break those rules
This is where ESLint (or your linter of choice) and GitHub Actions shine together like a passive-aggressive duo.
Step 1 — Pick Your Linter
For JavaScript or TypeScript, use ESLint. It’s flexible, powerful, and comes with fewer opinions than your senior developer.
Install it:
npm install eslint --save-dev
Initialize it:
npx eslint --init
This creates an .eslintrc file where you can define your rules.
I have a working linter for this project. You can check it out here: Marzsp’s Repo: Linter
Step 2 — Define Your Rules
In your .eslintrc file, you can specify rules.
For example, to enforce single quotes and disallow console logs:
{
"rules": {
"quotes": ["error", "single"],
"no-console": "warn"
}
}
You can find a full list of ESLint rules here.
Step 3 — How to make it work
Run the linter:
npx eslint .
This command checks all files in the current directory. To automatically fix problems where possible:
npx eslint . --fix
Step 4 — Automate with GitHub Actions
To make sure your linter runs on every push or pull request, set up a GitHub Action.
Create a file at .github/workflows/lint.yml:
name: lint
on:
push:
pull_request:
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm run lint
Let’s break down what this masterpiece does.
- What’s in a name?
lint
KISS. That means Keep It Simple, Stupid.
- Triggers
Runs on:
-
every push
-
every pull request
-
every time you make a typo in a branch name
-
every moment you least expect it just kidding
- Runner
ubuntu-latest
This is just GitHub’s polite way of saying: “We’re judging your code from a Linux box. Behave or the lil penguin will…”
- Steps
-
Checkout your repo
-
Install Node
-
Install dependencies
-
Run your linter
Now all you have to do is smile, ‘cos you’ve just built a linter! w00p!