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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@bernierllc/validators-editorial-style

v1.0.1

Published

Editorial style validation for the BernierLLC validators ecosystem - validates inclusive language, brand terms, prohibited terminology, and editorial tone

Downloads

14

Readme

@bernierllc/validators-editorial-style

Editorial style validation for the BernierLLC validators ecosystem. Validates inclusive language, brand terms, prohibited terminology, tone, and readability to ensure high-quality, professional documentation.

Installation

npm install @bernierllc/validators-editorial-style

Features

  • Inclusive Language: Detects non-inclusive terminology and suggests alternatives
  • Brand Terms: Validates correct capitalization of technology brands and terms
  • Prohibited Terms: Identifies weak, vague, or unprofessional language
  • Tone Validation: Ensures professional, respectful, and clear communication
  • Readability Score: Calculates Flesch Reading Ease score for content accessibility

Usage

Basic Validation

import { validateEditorialStyle } from '@bernierllc/validators-editorial-style';

const content = `
  Hey guys! This is a simple guide to using the API.
  Obviously, you should whitelist the master server.
`;

const problems = await validateEditorialStyle(content);

problems.forEach(problem => {
  console.log(`${problem.severity}: ${problem.message}`);
  if (problem.suggestion) {
    console.log(`  Suggestion: ${problem.suggestion}`);
  }
});

Using Individual Rules

import {
  inclusiveLanguage,
  brandTerms,
  prohibitedTerms,
  toneValidation,
  readabilityScore
} from '@bernierllc/validators-editorial-style';
import { createRuleContext } from '@bernierllc/validators-core';
import { createSharedUtils } from '@bernierllc/validators-utils';

const content = 'Your content here';
const context = createRuleContext('editorial-style', content, createSharedUtils());

// Run individual rules
const rule = inclusiveLanguage.create(context);
rule(content);

const problems = context.getProblems();

With Custom Utilities

import { validateEditorialStyle } from '@bernierllc/validators-editorial-style';
import { createSharedUtils } from '@bernierllc/validators-utils';

const utils = createSharedUtils();
const problems = await validateEditorialStyle(content, utils);

Validation Rules

1. Inclusive Language

Detects non-inclusive terminology and suggests inclusive alternatives:

Non-inclusive terms detected:

  • whitelistallowlist
  • blacklistdenylist/blocklist
  • masterprimary/main
  • slavesecondary/replica
  • guysfolks/everyone/team
  • manpowerworkforce/staff
  • sanity checkverification/validation
  • dummyplaceholder/sample
  • crazy/insaneunexpected/surprising

Example:

// ❌ Problematic
"Add the IP to the whitelist and configure the master server."

// ✅ Better
"Add the IP to the allowlist and configure the primary server."

2. Brand Terms

Validates correct capitalization of technology brands and terms:

Brands validated:

  • JavaScript (not javascript, Javascript)
  • TypeScript (not typescript, Typescript)
  • GitHub (not github, Github)
  • npm (not NPM, Npm)
  • Node.js (not nodejs, NodeJS)
  • API, URL, HTML, CSS, JSON (all caps)
  • macOS, iOS (specific capitalization)

Note: Skips validation inside code blocks (marked with backticks).

Example:

// ❌ Problematic
"Use javascript and github for your api."

// ✅ Better
"Use JavaScript and GitHub for your API."

3. Prohibited Terms

Identifies weak, vague, or unprofessional language:

Vague intensifiers: very, really Filler words: just, simply Condescending: obviously, clearly, easy, simple Informal: gonna, wanna, kinda, sorta Absolute statements: always, never, impossible Passive voice: it is believed, it is recommended

Example:

// ❌ Problematic
"This is very important. Just add the code and obviously it works."

// ✅ Better
"This is important. Add the code to enable the feature."

4. Tone Validation

Ensures professional, clear, and respectful communication:

Tone issues detected:

  • Condescending: "as you probably know", "of course", "needless to say"
  • Overly casual: "hey guys", "cool", "awesome", "!!"
  • Uncertain: "maybe", "perhaps", "I think", "??"
  • Bureaucratic: "herein", "pursuant to", "utilize"
  • Aggressive: "must", "cannot", "never do" (marked as errors)

Example:

// ❌ Problematic
"Obviously this is cool!! You must do this now."

// ✅ Better
"This approach is effective. We recommend implementing this feature."

5. Readability Score

Calculates Flesch Reading Ease score for content accessibility:

Score ranges:

  • 90-100: Very Easy (5th grade)
  • 80-89: Easy (6th grade)
  • 70-79: Fairly Easy (7th grade)
  • 60-69: Standard (8th-9th grade)
  • 50-59: Fairly Difficult (10th-12th grade)
  • 30-49: Difficult (College)
  • 0-29: Very Difficult (College graduate)

Target: 50-70 for technical documentation

Note: Skips content with fewer than 50 words. Removes code blocks before calculation.

API Reference

validateEditorialStyle(content: string, utils?: SharedUtils): Promise<Problem[]>

Main validation function that runs all editorial style rules.

Parameters:

  • content - The content string to validate
  • utils - Optional shared utilities (creates default if not provided)

Returns: Array of validation problems

Validators

editorialStyleValidator

Primitive validator instance for editorial style.

Properties:

  • meta.name - Validator name ("editorial-style")
  • meta.domain - Validation domain ("content")
  • validate(content, context) - Validation method

Metadata

metadata

Package metadata including version, description, and rule information.

Properties:

  • name - Package name
  • version - Package version
  • description - Package description
  • domain - Validation domain
  • rules - Array of rule metadata

Integration Status

  • Logger: Not applicable - Pure validation package
  • Docs-Suite: Ready - Exports markdown documentation
  • NeverHub: Not applicable - Primitive validator with no service dependencies

Examples

Complete Validation Example

import { validateEditorialStyle } from '@bernierllc/validators-editorial-style';

const documentation = `
  # API Documentation

  Hey guys! This is a very simple guide to using our API.

  Obviously, you should whitelist your IP addresses on the master server.
  The api uses JSON for all responses. Just send a GET request to get data.

  It's impossible to mess this up - the system always works perfectly!
`;

const problems = await validateEditorialStyle(documentation);

// Group problems by severity
const errors = problems.filter(p => p.severity === 'error');
const warnings = problems.filter(p => p.severity === 'warn');
const info = problems.filter(p => p.severity === 'info');

console.log(`Found ${errors.length} errors, ${warnings.length} warnings, ${info.length} info`);

// Show problems with suggestions
problems.forEach(problem => {
  console.log(`\n${problem.severity.toUpperCase()}: ${problem.message}`);

  if (problem.evidence?.snippet) {
    console.log(`  Context: "${problem.evidence.snippet}"`);
  }

  if (problem.suggestion) {
    console.log(`  💡 ${problem.suggestion}`);
  }
});

Custom Rule Set

import { createPrimitiveValidator } from '@bernierllc/validators-core';
import {
  inclusiveLanguage,
  brandTerms,
  readabilityScore
} from '@bernierllc/validators-editorial-style';

// Create validator with subset of rules
const customValidator = createPrimitiveValidator(
  'custom-editorial',
  'content',
  [inclusiveLanguage, brandTerms, readabilityScore]
);

// Use custom validator
const context = createRuleContext('custom-editorial', content, createSharedUtils());
const problems = await customValidator.validate(content, context);

CI/CD Integration

import { validateEditorialStyle } from '@bernierllc/validators-editorial-style';
import * as fs from 'fs';

async function validateDocumentation(filePath: string): Promise<boolean> {
  const content = fs.readFileSync(filePath, 'utf-8');
  const problems = await validateEditorialStyle(content);

  const errors = problems.filter(p => p.severity === 'error');

  if (errors.length > 0) {
    console.error(`❌ ${errors.length} editorial errors in ${filePath}`);
    errors.forEach(e => console.error(`  - ${e.message}`));
    return false;
  }

  const warnings = problems.filter(p => p.severity === 'warn');
  if (warnings.length > 0) {
    console.warn(`⚠️  ${warnings.length} editorial warnings in ${filePath}`);
    warnings.forEach(w => console.warn(`  - ${w.message}`));
  }

  return true;
}

// Validate all markdown files
const docFiles = ['README.md', 'docs/api.md', 'docs/guide.md'];
const results = await Promise.all(docFiles.map(validateDocumentation));

if (!results.every(r => r)) {
  process.exit(1);
}

Best Practices

  1. Run in CI/CD: Include editorial validation in your continuous integration pipeline
  2. Combine with Linters: Use alongside ESLint and Prettier for comprehensive code quality
  3. Document Exceptions: When false positives occur, document why specific terms are acceptable
  4. Educate Team: Share validation results to improve writing across your team
  5. Iterate: Start with errors only, gradually address warnings as team improves

Development

# Install dependencies
npm install

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

# Build
npm run build

# Lint
npm run lint

License

Copyright (c) 2025 Bernier LLC. All rights reserved.

See Also