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-nlp

v1.19.0

Published

Optional NLP-powered ruleset for faircopy using compromise

Readme

@faircopy/rules-nlp

Optional NLP-powered ruleset for faircopy using compromise.

npm i -D @faircopy/rules-nlp

Load the ruleset once, then configure rules with bare rule IDs:

rulesets: ['@faircopy/rules-nlp'],
rules: {
  'no-absolute-intensifiers': 'warn',
  'no-adverb-overuse': 'warn',
  'no-expletive-openers': 'warn',
  'no-filter-words': 'warn',
  'no-future-promises': 'warn',
  'no-hedge-words': 'warn',
  'no-empty-transformation-claims': 'warn',
  'no-passive-voice': 'warn',
  'no-qualifier-creep': 'warn',
  'no-redundant-pairs': 'warn',
  'no-vague-comparatives': 'warn',
  'no-weak-modals': 'warn',
  'no-stacked-adjectives': 'warn',
  'no-nominalized-phrases': 'warn',
  'no-noun-strings': 'warn',
  'no-pronoun-led-claims': 'warn',
  'no-buzzword-stacks': 'warn',
  'no-complex-readability': 'warn',
  'no-overly-complex-sentences': 'warn',
  'no-vague-quantifiers': 'warn',
  'no-meaningless-modifiers': 'warn',
  'no-superlative-claims': 'warn',
  'no-llm-speak': 'warn',
}

Package-qualified IDs like @faircopy/rules-nlp/no-passive-voice still work and are required if another loaded ruleset exposes the same bare rule name.

Rules

| Rule | Description | |---|---| | no-absolute-intensifiers | Flag intensifiers before absolute adjectives like very unique | | no-adverb-overuse | Flag sentences with more than two adverbs ending in -ly | | no-empty-transformation-claims | Flag broad transformation cliches like transform the way teams work | | no-expletive-openers | Flag sentence openings like There are | | no-filter-words | Ban filter phrases like I think and it seems | | no-future-promises | Flag future-tense promises like will help you | | no-hedge-words | Flag hedge words like kind of and somewhat | | no-jargon | Flag business jargon like leverage and circle back | | no-passive-voice | Flag likely passive-voice constructions | | no-qualifier-creep | Flag stacked qualifiers or intensifiers like very really good | | no-redundant-pairs | Flag redundant fixed phrases like first and foremost | | no-vague-comparatives | Flag comparative claims that omit a clear baseline | | no-weak-modals | Flag hedged modal claims like can help and might improve | | no-stacked-adjectives | Flag noun phrases with multiple adjectives before the noun | | no-nominalized-phrases | Flag nominalized X of Y phrases like optimization of onboarding | | no-noun-strings | Flag dense strings of consecutive nouns like user experience design process | | no-pronoun-led-claims | Flag vague sentence openers like This helps and It enables | | no-buzzword-stacks | Flag sentences overloaded with abstract benefit nouns | | no-complex-readability | Flag prose whose Flesch-Kincaid grade level exceeds a target | | no-overly-complex-sentences | Flag sentences overloaded with coordinating or subordinating conjunctions | | no-vague-quantifiers | Flag bare quantifiers without numeric anchors | | no-meaningless-modifiers | Flag intensifiers like very and obviously that add no information | | no-superlative-claims | Flag unproven superlatives like best and world-class | | no-non-inclusive-language-nlp | Flag non-inclusive terms and suggest neutral alternatives | | no-llm-speak | Flag LLM clichés like delve into and robust and suggest concrete alternatives | | sentence-complexity | Flag sentences that exceed a word or clause threshold |

no-absolute-intensifiers

Absolute adjectives already express an extreme, so intensifiers such as very are redundant.

rules: {
  'no-absolute-intensifiers': 'warn',
}

Options:

| Option | Type | Default | Description | |---|---|---|---| | intensifiers | string[] | ['very', 'really', 'completely', ...] | Words or phrases to treat as intensifiers | | absolutes | string[] | ['unique', 'finished', 'destroyed', ...] | Absolute adjectives that should not be intensified |

Example:

'no-absolute-intensifiers': ['warn', {
  intensifiers: ['very', 'highly'],
  absolutes: ['unique', 'critical'],
}]

sentence-complexity

Long, clause-heavy sentences are harder to read. This rule flags any sentence that exceeds a configurable word count or contains too many finite-verb clauses, and suggests splitting it into shorter sentences.

rules: {
  'sentence-complexity': 'warn',
}

Options:

| Option | Type | Default | Description | |---|---|---|---| | maxWordCount | number | 25 | Maximum words allowed per sentence | | maxClauseCount | number | 3 | Maximum finite-verb clauses allowed per sentence |

Example with custom thresholds:

'sentence-complexity': ['warn', {
  maxWordCount: 20,
  maxClauseCount: 2,
}]

Flagged example:

The engineer reviewed the requirements and wrote the code and ran the tests and deployed the application while the team watched and celebrated the release together.

Suggested fix: split the sentence around each independent clause.

The engineer reviewed the requirements. They wrote the code, ran the tests, and deployed the application. The team watched and celebrated the release together.

no-overly-complex-sentences

Sentences packed with conjunctions are often run-ons or nested too deeply. This rule flags any sentence that exceeds a configurable number of coordinating conjunctions, subordinating conjunctions, or total conjunctions.

rules: {
  'no-overly-complex-sentences': 'warn',
}

Options:

| Option | Type | Default | Description | |---|---|---|---| | maxConjunctions | number | 4 | Maximum total conjunctions allowed per sentence | | maxCoordinating | number | 3 | Maximum coordinating conjunctions allowed per sentence | | maxSubordinating | number | 2 | Maximum subordinating conjunctions allowed per sentence | | coordinating | string[] | ['and', 'but', 'or', 'nor', 'yet', 'so'] | Words treated as coordinating conjunctions | | subordinating | string[] | ['because', 'although', 'though', 'while', 'since', 'unless', 'if', 'when', 'after', 'before', 'until', 'whether', 'once'] | Words treated as subordinating conjunctions | | allowList | string[] | [] | Words to ignore when counting |

Example with custom thresholds:

'no-overly-complex-sentences': ['warn', {
  maxConjunctions: 3,
  maxCoordinating: 2,
  maxSubordinating: 1,
}]

Flagged example:

I ran and swam and biked and hiked and climbed.

Suggested fix: split the list into shorter sentences or use a bulleted list.

I ran, swam, and biked. Then I hiked and climbed.

Some words, such as since or so, can be prepositions or adverbs in certain contexts. If the rule is too noisy for your copy, add the word to allowList.

no-vague-comparatives

Comparative claims like faster, easier, or more efficient only persuade when the reader knows the baseline. This rule flags comparative adjectives and adverbs that are not paired with than in the same sentence.

rules: {
  'no-vague-comparatives': 'warn',
}

Options:

| Option | Type | Default | Description | |---|---|---|---| | comparatives | string[] | ['better', 'worse', 'more', 'less', 'faster', 'slower', 'easier', 'harder', 'stronger', 'weaker', 'higher', 'lower', 'bigger', 'smaller', 'greater'] | Comparative words or phrases that require a baseline | | requireThan | boolean | true | Whether a than in the same sentence suppresses the diagnostic |

Example with custom settings:

'no-vague-comparatives': ['warn', {
  comparatives: ['superior', 'inferior', 'better'],
  requireThan: true,
}]

Flagged example:

Our editor is faster. It is also easier to use.

Suggested fix: add a concrete baseline.

Our editor is faster than the old one. It is also easier to use than a spreadsheet.

no-qualifier-creep

Stacked qualifiers or intensifiers dilute a claim and make it sound hedged. This rule flags sequences of two or more qualifiers before an adjective or adverb.

rules: {
  'no-qualifier-creep': 'warn',
}

Options:

| Option | Type | Default | Description | |---|---|---|---| | qualifiers | string[] | ['very', 'really', 'quite', ...] | Words treated as qualifiers or intensifiers | | maxQualifiers | number | 1 | Maximum qualifiers allowed in a row before the excess are flagged |

Example with custom settings:

'no-qualifier-creep': ['warn', {
  qualifiers: ['very', 'really', 'quite'],
  maxQualifiers: 1,
}]

Flagged example:

The result is very really quite good.

Suggested fix: keep the strongest qualifier or replace the phrase with concrete evidence.

The result is excellent.

no-non-inclusive-language-nlp

Non-inclusive terms can alienate readers. This rule flags common non-inclusive language and suggests neutral alternatives using NLP-aware matching so it understands word boundaries and part-of-speech context.

rules: {
  'no-non-inclusive-language-nlp': 'warn',
}

Options:

| Option | Type | Default | Description | |---|---|---|---| | terms | NonInclusiveTerm[] | See source | Terms to flag, each with a list of alternatives | | allowedTerms | string[] | [] | Terms to allow and skip |

Example with custom terms:

'no-non-inclusive-language-nlp': ['warn', {
  terms: [
    { term: 'guys', alternatives: ['everyone', 'team', 'folks'] },
    { term: 'blacklist', alternatives: ['denylist', 'blocklist'] },
  ],
  allowedTerms: ['whitelist'],
}]

Flagged example:

Hey guys, add this to the blacklist and do a sanity check.

Suggested fix:

Hey everyone, add this to the blocklist and do a quick check.

The rule uses compromise to avoid partial-word matches (e.g., guyses is not flagged) and skips verb-only usages of ambiguous words such as master in master the skill.

no-llm-speak

LLM-generated copy often falls back to padded, abstract phrases that sound authoritative without saying much. This rule flags common LLM clichés and suggests concrete replacements.

rules: {
  'no-llm-speak': 'warn',
}

Options:

| Option | Type | Default | Description | |---|---|---|---| | phrases | LlmSpeakPhrase[] | See source | Phrases to flag, each with a list of alternatives | | allowedPhrases | string[] | [] | Phrases to allow and skip |

Example with custom phrases:

'no-llm-speak': ['warn', {
  phrases: [
    { phrase: 'delve into', alternatives: ['explore', 'examine'] },
    { phrase: 'robust', alternatives: ['strong', 'resilient'] },
  ],
  allowedPhrases: ['crucial'],
}]

Flagged example:

It's important to note that we will delve into the robust, intricate tapestry. Furthermore, the system is crucial.

Suggested fix:

Note that we will explore the strong, detailed pattern. Also, the system is critical.

The rule uses compromise for word-aware matching, so robustness is not flagged when the configured phrase is robust.

no-noun-strings

Three or more nouns in a row create dense, hard-to-read compounds. This rule flags consecutive noun strings and suggests rewriting them with verbs or prepositions.

rules: {
  'no-noun-strings': 'warn',
}

Options:

| Option | Type | Default | Description | |---|---|---|---| | maxConsecutiveNouns | number | 3 | Maximum consecutive nouns allowed before flagging | | allowedPhrases | string[] | [] | Phrases to allow and skip |

Example with custom settings:

'no-noun-strings': ['warn', {
  maxConsecutiveNouns: 4,
  allowedPhrases: ['user experience design process'],
}]

Flagged example:

The user experience design process is slow.

Suggested fix:

The process for designing the user experience is slow.

The rule uses compromise for part-of-speech tagging and skips proper nouns such as place names.