npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@cadencejs/eslint-plugin

v0.1.0

Published

An experimental, **brutally strict** ESLint config for **forcing** clean, less-buggy TypeScript code.

Downloads

2

Readme

Cadence (Alpha)

Cadence is an experimental, brutally strict ESLint config for forcing clean, less-buggy TypeScript code.

NOTE: Cadence is an experimental config, and in its very early phases. I can be swayed on some rules. Make a discussion or an issue on this repo and I'll get to it!

NOTE: Cadence is a preset compiling mostly other peoples hard work. If you like this, you should support upstream.

Try it out on your own code!

The Cadence Playground will automatically show how Cadence treats your code.

What's the point?

  • It's brutally strict. (The config is nearly one thousand lines long.)

Now, let's be honest. TypeScript has a lot of warts and footguns. TS would arguably be a better language if we could just cut off the bad parts. So let's do it! Cadence is strict to the point where these footguns are caught for you at lint time. No longer do you have to fall for subtle JS-isms like these:

isNaN("foo"); // true
Number.isNaN("foo"); // false
function doStuff() {
    switch (foo) {
        case "bar":
            let thing = 5;
            return thing;
        case "baz":
            let thing = 6; // SyntaxError, thing is already defined !!!
            return thing;
    }
}
const users = ["joey", "tim", "bob"];

// This actually happens in parallel !!
users.forEach(async user => {
    console.log(`Fetching ${user}'s email...`);
    const usersEmail = await fetch(`https://example.com/api/user-email?user=${user}`).then(r => r.text());

    console.log(`Got ${usersEmail}!`)
})

console.log(`Done!`);

// Will output something like:
// Done!
// -- the order of everything below this point is non-determinis tic!
// Fetching joey's email...
// Fetching tim's email...
// Fetching bob's email...
// Got [email protected]!
// Got [email protected]!
// Got [email protected]!

When developing Cadence, I was honestly unconvinced of its merit. However, after it found 14 bugs (some of which were serious!) in one of my codebases (~50kloc), I was completely sold.

  • All code linted and formatted with the Cadence config must have the same format and rhythm to it. (get it?)

You even get cleaner git diffs for free. Your imports? Those are automatically put in the right place by the linter. Typescript union order? Deterministic.

  • Cadence code is forced to be easily legible.

Cadence enforces whitespace, padding and other pretty-isms around the codebase to split up logic visually.

You might think this is nitpicky, but since it can be enforce automatically, all code with Cadence is guaranteed not to be a clumped mess of logic.

It is extremely difficult to write messy code with Cadence enabled!

Logic should be separated, and sparse! We shouldn't have to think about anything other than business logic while reading code.

function scrimbly() {
    const foo = "asdf";
    const bar = 123;
    let {more, variables} = scrobbly(bar);
    // subFunction foos the bar and scrimbles the bimble
    function subFunction() {
        return 1;
    }
    if (statement) { 
        doThing();
    }
    return foo;
}

Will be forcibly changed to:

function scrimbly() {
    const foo = "asdf";
    const bar = 123;
    const { more, variables } = scrobbly(bar);

    // subFunction foos the bar and scrimbles the bimble
    function subFunction() {
        return 1;
    }

    if (statement) {
        doThing();
    }

    return foo;
}

Using Cadence properly

A lot of Cadence's linting/formatting opinions will be automatically fixed. It would be a very frustrating experience to have to go through the codebase and apply Cadence's changes by hand!

Similarly, Cadence is intended to be a real-time feedback loop on your codebase. As such, it's intended to be used by running on save in your editor of choice. For VSCode, this just means setting ESLint as your default formatter.

Tools are here to help you!

Cadence might be frustrating at times, the same way something like TypeScript's type checking is. At its core though, Cadence and TS are trying to do the exact same thing - Stop you from making mistakes! It might be frustrating to work around hoops when you think you know your code is safe, but when it actually saves your bacon, it's all worth it.

Sometimes, however, Cadence might just be straight up incorrect about parts of your code. To get around this, use the standard ESLint ignore syntax.

// eslint-disable-next-line rule-thats-giving-you-trouble

If you're doing something across your codebase that Cadence is giving you trouble about, you might want to reduce it to a warning in your .eslintrc.

{
    "plugins": [
        "cadence"
    ],
    "extends": [
        "plugin:cadence/recommended"
    ],
    	"rules": {
		"@typescript-eslint/no-unsafe-assignment": "warn"
	},
}

Don't set rules to "off" unless you know EXACTLY what you're doing. Leaving would-be errors as warnings is useful for other developers -- they'll know something is out-of-the-ordinary here!

What's the point of rule (xyz)?

At the moment, you'll have to check src/configs/recommended.ts in this repository to see my stance on each rule. In the future, I hope to have documentation for why every single rule is enabled. This would double up as a very useful resource on JS/TS footguns!

If the explanation in there doesn't satisfy, feel free to open a Discussion.

Setup (Fresh Repository)

You'll first need to install ESLint and this plugin:

# Use your preferred package manager. If you don't have strong opinions on this, here's mine.
# I would **highly** recommend pnpm, as its the most sensible.
pnpm add eslint -D

# Yarn is also pretty good, but there's a couple of pain points and generally
# worse performance.
yarn add eslint -D

# use NPM if you have to. It's slow, riddled with design flaws, and generally a pain
# in the ass.
npm i eslint @cadence/ --save-dev

Next, install eslint-plugin-cadence:

npm install  --save-dev

# or
yarn add eslint-plugin-cadence -D

# or
pnpm add eslint-plugin-cadence -D

Usage

Create an .eslintrc file next to your package.json. Fill it with the following content.

{
    "plugins": [
        "cadence"
    ],
    "extends": [
        "plugin:cadence/recommended"
    ],
}

You might want to also make an .eslintignore file:

# We don't want to lint node_modules! 
node_modules

Migrating to Cadence

Migrating a codebase to Cadence is honestly a pain in the ass. Although it can automatically fix a hell of a lot of the issues in your codebase, you will almost certainly have to do some manual work.

This is especially true if you depend on unsafe/unclean things throughout your codebase, such as a liberal use of any, for (const k in obj), [].forEach(), etc.

In my opinion, the best way to migrate to Cadence is as follows:

  1. Make a new git branch off of your main branch.
  2. Install Cadence there, and run eslint . --fix --ext .ts
  3. It'll likely give you some errors and warnings. Step through them all and start analysing them.
  4. It's quite likely it'll find some bugs in your codebase, aswell! That should hopefully convince you it's worth the setup effort.
  5. If you don't like it though, you can always just straight up discard the branch and go back to normal.
  6. Once you've analysed and fixed all of the errors and warnings, merge it back into your main branch!