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

eslint-plugin-lexmata

v1.3.0

Published

ESLint Plugin for all Lexmata.ai projects

Readme

eslint-plugin-lexmata

npm version License: ISC

An ESLint plugin for all Lexmata.ai projects that enforces TypeScript code quality standards with a focus on explicit visibility declarations and consistent class member ordering.

Features

  • 🔒 Explicit Public Methods: Enforces explicit public declarations on class methods
  • 📋 Member Ordering: Enforces a consistent ordering of class members
  • 🏷️ Private Member Prefix: Enforces underscore prefix on private class members (not functions)
  • Angular Signals: Prefers Angular signals over RxJS observables when appropriate
  • 🔧 Auto-fixable: All rules provide automatic fixes
  • 📦 TypeScript Ready: Built specifically for TypeScript projects
  • Zero Configuration: Works out of the box with recommended config

Installation

npm install --save-dev eslint-plugin-lexmata

or with pnpm:

pnpm add -D eslint-plugin-lexmata

or with yarn:

yarn add --dev eslint-plugin-lexmata

Quick Start

Add the plugin to your ESLint configuration:

ESLint v9+ (Flat Config)

import lexmataPlugin from 'eslint-plugin-lexmata';

export default [
  {
    plugins: {
      'lexmata': lexmataPlugin
    },
    rules: {
      'lexmata/explicit-public-methods': 'error',
      'lexmata/member-ordering': 'error',
      'lexmata/private-member-prefix': 'error',
      'lexmata/prefer-angular-signals': 'error'
    }
  }
];

ESLint v8 (Legacy Config)

{
  "plugins": ["lexmata"],
  "rules": {
    "lexmata/explicit-public-methods": "error",
    "lexmata/member-ordering": "error",
    "lexmata/private-member-prefix": "error",
    "lexmata/prefer-angular-signals": "error"
  }
}

Using Recommended Configuration

import lexmataPlugin from 'eslint-plugin-lexmata';

export default [
  lexmataPlugin.configs.recommended
];

Rules

lexmata/explicit-public-methods

Enforces explicit public declarations on class methods to improve code clarity and consistency.

❌ Incorrect

class Example {
  method() {  // Missing explicit 'public'
    return 'hello';
  }

  getValue() {  // Missing explicit 'public'
    return this.value;
  }
}

✅ Correct

class Example {
  public method() {
    return 'hello';
  }

  public getValue() {
    return this.value;
  }

  private privateMethod() {  // Private methods are allowed without 'public'
    return 'private';
  }

  protected protectedMethod() {  // Protected methods are allowed
    return 'protected';
  }

  #privateField() {  // Private fields are allowed
    return 'private field';
  }
}

lexmata/member-ordering

Enforces a specific ordering of class members to improve code organization and readability.

Required Order

  1. Public properties
  2. Protected properties
  3. Private properties
  4. Constructor
  5. Public getters/setters
  6. Public methods
  7. Protected methods
  8. Private methods
  9. Private fields (using # syntax)

❌ Incorrect

class Example {
  constructor() {}  // Constructor should come after properties
  private prop1: string;  // Private property in wrong position
  method1() {}  // Missing 'public' and wrong position
  protected method2() {}  // Wrong position
  get value() {}  // Missing 'public' and wrong position
  public prop2: string;  // Public property in wrong position
}

✅ Correct

class Example {
  public prop2: string;  // Public properties first
  protected prop3: string;  // Protected properties
  private prop1: string;  // Private properties

  constructor() {}  // Constructor after properties

  public get value() {  // Public getters/setters
    return this._value;
  }

  public set value(v: string) {
    this._value = v;
  }

  public method1() {}  // Public methods
  public method2() {}

  protected method3() {}  // Protected methods

  private method4() {}  // Private methods

  #privateField: string;  // Private fields last
}

lexmata/private-member-prefix

Enforces underscore prefix on private class members (properties and fields) to improve code clarity and distinguish them from public members. This rule only applies to private members that are not functions.

❌ Incorrect

class Example {
  private property: string;
  private field = 'value';
  private number: number = 42;
}

✅ Correct

class Example {
  private _property: string;
  private _field = 'value';
  private _number: number = 42;

  // Methods are not affected by this rule
  private method() {}
  private _privateMethod() {}
}

lexmata/prefer-angular-signals

Encourages the use of Angular signals (signal, computed, effect) over RxJS observables and BehaviorSubjects, except when dealing with Angular resources that still use RxJS (like HttpClient, Router, FormControl).

❌ Incorrect

import { BehaviorSubject, of, from } from 'rxjs';

class Example {
  private data = new BehaviorSubject('initial');
  
  getData() {
    return of('data');
  }
  
  ngOnInit() {
    this.data.subscribe(value => {
      console.log(value);
    });
  }
}

✅ Correct

import { signal, computed, effect } from '@angular/core';

class Example {
  private _data = signal('initial');
  private _computed = computed(() => this._data() + ' processed');
  
  constructor() {
    effect(() => {
      console.log(this._data());
    });
  }
}

Angular Resources Exception

The rule allows RxJS usage when dealing with Angular resources that still use RxJS:

import { HttpClient } from '@angular/common/http';
import { ActivatedRoute } from '@angular/router';
import { FormControl } from '@angular/forms';

class Service {
  constructor(private http: HttpClient, private route: ActivatedRoute) {}
  
  // ✅ Allowed - HttpClient still uses RxJS
  getData() {
    return this.http.get('/api/data');
  }
  
  // ✅ Allowed - Router still uses RxJS
  ngOnInit() {
    this.route.params.subscribe(params => {
      console.log(params);
    });
  }
  
  // ✅ Allowed - FormControl still uses RxJS
  control = new FormControl('');
  ngOnInit() {
    this.control.valueChanges.subscribe(value => {
      console.log(value);
    });
  }
}

Configuration Options

All rules currently have no configuration options and work with their default behavior. They are designed to be zero-configuration for consistent code style across Lexmata.ai projects.

Auto-fixing

All rules support ESLint's --fix option:

eslint --fix your-file.ts

The rules will automatically:

  • Add missing public declarations
  • Reorder class members according to the specified order
  • Add underscore prefixes to private members
  • Convert BehaviorSubject to signal() where appropriate
  • Maintain proper indentation and formatting

Development

Prerequisites

  • Node.js 16+
  • pnpm (recommended) or npm

Setup

# Clone the repository
git clone <repository-url>
cd eslint-plugin-lexmata

# Install dependencies
pnpm install

# Build the plugin
pnpm run build

# Run tests
pnpm test

# Run linting
pnpm run lint

Project Structure

eslint-plugin-lexmata/
├── src/
│   ├── index.ts              # Plugin entry point
│   └── rules/
│       ├── explicit-public-methods.ts
│       ├── member-ordering.ts
│       ├── private-member-prefix.ts
│       └── prefer-angular-signals.ts
├── tests/
│   └── rules/
│       ├── explicit-public-methods.test.ts
│       ├── member-ordering.test.ts
│       ├── private-member-prefix.test.ts
│       └── prefer-angular-signals.test.ts
├── dist/                     # Built output (generated)
├── package.json
├── tsconfig.json
├── jest.config.js
└── eslint.config.js

Available Scripts

  • pnpm run build - Compile TypeScript to JavaScript
  • pnpm test - Run Jest tests
  • pnpm run lint - Run ESLint on source code
  • pnpm run prepare - Build before publishing (runs automatically)

Testing

The plugin uses Jest with TypeScript support and the official @typescript-eslint/rule-tester for testing ESLint rules.

pnpm test

Tests cover:

  • Valid code examples that should pass
  • Invalid code examples that should fail
  • Auto-fix functionality
  • Edge cases and error conditions

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Add tests for your changes
  5. Ensure all tests pass (pnpm test)
  6. Ensure linting passes (pnpm run lint)
  7. Commit your changes (git commit -m 'Add amazing feature')
  8. Push to the branch (git push origin feature/amazing-feature)
  9. Open a Pull Request

Peer Dependencies

  • ESLint >= 8.0.0

Dependencies

  • @typescript-eslint/utils ^8.15.0

License

ISC License - see the LICENSE.md file for details.

Changelog

v1.3.0

  • Added lexmata/prefer-angular-signals rule to encourage Angular signals over RxJS observables
  • Supports auto-fix for BehaviorSubject to signal() conversion
  • Excludes Angular resources that still use RxJS (HttpClient, Router, FormControl)
  • Updated documentation with Angular signals examples

v1.2.0

  • Added lexmata/private-member-prefix rule to enforce underscore prefix on private class members (not functions)
  • Full auto-fix support for the new rule
  • Updated documentation and examples

v1.1.1

  • Current stable release
  • Includes explicit-public-methods and member-ordering rules
  • Full auto-fix support
  • TypeScript support

Support

For issues, feature requests, or questions:


Made with ❤️ by the Lexmata.ai team