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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@faircopy/rules-default

v1.23.0

Published

Default ruleset for faircopy: no-complex-sentences, no-em-dash, no-weasel-words, no-rhetorical-scaffolding, no-non-inclusive-language, no-redundant-phrases, no-passive-voice, no-cliches, no-repetitive-sentence-startings, no-filler-words

Readme

@faircopy/rules-default

Default ruleset for faircopy. Ships nine rules targeting the most common landing-page copy patterns.

Install

Included automatically when you install faircopy. To use standalone:

npm i @faircopy/rules-default

Rules

no-complex-sentences

Flags individual sentences whose Flesch-Kincaid grade level exceeds a target.

warn[no-complex-sentences]: sentence readability is grade 18.5 — simplify to 12 or below

Options:

{
  maxGradeLevel?: number  // Default: 12
  minWords?: number       // Minimum words before scoring a sentence. Default: 10
}

Config example:

rules: {
  'no-complex-sentences': ['warn', { maxGradeLevel: 10, minWords: 8 }],
}

no-em-dash

Bans the em-dash character (—, U+2014) in marketing copy.

error[no-em-dash]: use a sentence break instead of an em-dash

Options:

{
  flagEnDash?: boolean        // Also flag en-dashes (–). Default false.
  flagDoubleHyphen?: boolean  // Also flag --. Default false.
}

Config example:

rules: {
  'no-em-dash': ['error', { flagDoubleHyphen: true }],
}

no-weasel-words

Bans reinforcement adverbs that weaken claims.

error[no-weasel-words]: remove "actually" — it weakens the claim

Options:

{
  words: string[]  // Default: ['actually', 'truly', 'really', 'literally']
}

Config example:

rules: {
  'no-weasel-words': ['error', { words: ['actually', 'truly', 'really', 'literally', 'just', 'simply'] }],
}

no-filler-words

Bans filler words that pad out a sentence without adding meaning.

error[no-filler-words]: remove "just" — it's filler

Options:

{
  words: string[]  // Default: ['just']
}

Config example:

rules: {
  'no-filler-words': ['error', { words: ['just', 'basically', 'literally'] }],
}

no-rhetorical-scaffolding

Bans two formulaic patterns:

  1. X is Y, not Z constructions
  2. Without X... With X... sentence pairs
error[no-rhetorical-scaffolding]: avoid "X is Y, not Z" — state the claim directly
error[no-rhetorical-scaffolding]: avoid "Without X / With X" — drop the setup and make the claim

Options:

{
  allowIsNotConstruction?: boolean       // Disable pattern 1. Default false.
  allowWithoutWithConstruction?: boolean // Disable pattern 2. Default false.
  extraPatterns?: string[]               // Additional regex patterns to ban.
}

no-non-inclusive-language

Flags non-inclusive terms and suggests neutral alternatives.

error[no-non-inclusive-language]: replace "guys" with a neutral alternative such as "everyone, team, folks"

Default terms:

| Term | Suggested alternatives | |---|---| | guys | everyone, team, folks | | manpower | workforce, staffing, personnel | | whitelist | allowlist | | blacklist | denylist, blocklist | | master | primary, main, leader | | slave | secondary, replica, follower | | crazy | unexpected, intense, extreme | | insane | extreme, unbelievable, remarkable | | dumb | unhelpful, poor, uninformed | | lame | unimpressive, inadequate, weak | | sanity check | quick check, confidence check, verification | | blind spot | unaware area, gap, oversight | | grandfathered | legacy status, exempted | | mankind | humanity, humankind, people |

Options:

{
  terms?: { term: string; alternatives: string[]; exact?: boolean }[]
  allowedTerms?: string[]
}

Config example:

rules: {
  'no-non-inclusive-language': ['error', {
    terms: [
      { term: 'guys', alternatives: ['everyone', 'team'] },
      { term: 'rockstar', alternatives: ['expert', 'skilled'] },
    ],
    allowedTerms: ['master'],
  }],
}

Single-word terms always match with word boundaries, so master will not flag masterpiece. Default multi-word phrases such as sanity check and blind spot use exact: true, so sanity checker is not flagged. Set exact: false on a custom multi-word term to match it as a substring anywhere in the text.

allowedTerms is case-insensitive: adding master also permits Master or MASTER.


no-redundant-phrases

Flags wordy redundant phrases and suggests concise replacements.

Default phrases include:

| Phrase | Suggested replacement | |---|---| | in order to | to | | due to the fact that | because | | in spite of the fact that | although | | at this point in time | now | | in the event that | if | | for the purpose of | to | | with regard to | about | | in close proximity to | near | | a large number of | many | | the reason is that | because | | it is important to note that | (delete) | | needless to say | (delete) |

warn[no-redundant-phrases]: "in order to" is redundant — use "to"

Options:

{
  phrases?: { phrase: string; replacement: string }[]
}

Config example:

rules: {
  'no-redundant-phrases': ['warn', {
    phrases: [
      { phrase: 'in order to', replacement: 'to' },
      { phrase: 'touch base', replacement: 'talk' },
    ],
  }],
}

Set replacement to an empty string to suggest deleting the phrase entirely.


no-cliches

Flags overused or clichéd phrases and suggests fresher alternatives.

Default phrases include:

| Phrase | Suggested alternatives | |---|---| | world-class | top-tier, exceptional, outstanding | | best-in-class | leading, top-performing, category-leading | | cutting-edge | advanced, modern, latest | | state-of-the-art | advanced, modern, sophisticated | | game changer | breakthrough, transformation, major advance | | think outside the box | be creative, innovate, find a new approach | | at the end of the day | ultimately, finally, in summary | | low-hanging fruit | easy wins, quick opportunities, simple targets | | move the needle | make a measurable difference, drive results, create impact | | circle back | follow up, reconnect, return to this | | hit the ground running | start quickly, get started immediately, begin effectively | | boil the ocean | take on too much, overcomplicate, lose focus | | paradigm shift | fundamental change, new approach, transformation | | next level | advanced, improved, elevated | | seamless | smooth, effortless, frictionless | | robust | strong, resilient, reliable | | leverage | use, take advantage of, utilize | | synergy | collaboration, combined effect, partnership |

warn[no-cliches]: replace "world-class" with a fresher alternative such as "top-tier, exceptional, outstanding"

Options:

{
  phrases?: { phrase: string; alternatives: string[] }[]
  allow?: string[]
}

Config example:

rules: {
  'no-cliches': ['warn', {
    phrases: [
      { phrase: 'world-class', alternatives: ['top-tier', 'exceptional'] },
      { phrase: 'low-hanging fruit', alternatives: ['easy wins'] },
    ],
    allow: ['robust'],
  }],
}

no-passive-voice

Flags likely passive-voice constructions using auxiliary + past participle patterns.

warn[no-passive-voice]: rewrite passive construction "was approved" with a named actor

Passive voice often hides the actor and adds drag. Prefer naming who did the action unless the actor genuinely does not matter.

Options:

{
  auxiliaries?: string[]  // Default: ['is', 'are', 'was', 'were', 'be', 'been', 'being']
  participles?: string[]  // Past participles to flag. Default is a curated list of common action participles.
  allowedPhrases?: string[] // Phrases to allow even if they match the passive pattern.
}

Config example:

rules: {
  'no-passive-voice': ['warn', {
    allowedPhrases: ['is licensed', 'was founded'],
  }],
}