🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

eslint-plugin-apex

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-apex

ESLint plugin for Salesforce Apex — ports PMD Apex rules to the ESLint ecosystem

latest
Source
npmnpm
Version
0.1.1
Version published
Weekly downloads
1
-66.67%
Maintainers
1
Weekly downloads
 
Created
Source

eslint-plugin-apex

ESLint plugin for Salesforce Apex — inspired by apex-pmd, this plugin ports 57 ESLint rules that align with the PMD Apex rule set into the ESLint ecosystem so that teams working with Salesforce can use a single linting tool for both Apex and Lightning Web Components (LWC) side by side.

If you already use eslint-plugin-lwc for your LWC code, adding eslint-plugin-apex brings your Apex codebase into the same workflow — one eslint.config.js, one npm run lint command, one CI step.

The plugin is backed by the ANTLR4-based @apexdevtools/apex-parser for accurate, whitespace-aware parsing rather than regex heuristics.

Status: Early release. Parser coverage is solid for classes and triggers; advanced patterns (anonymous Apex, complex generics) are progressively improved.

Features

  • 57 rules across 7 categories (Best Practices, Code Style, Design, Documentation, Error Prone, Performance, Security), each with a Markdown page under docs/rules/
  • Custom ANTLR4-backed parser — no regex heuristics
  • ESLint flat config API (v9+)
  • Four ready-made shared configs: recommended, strict, security, performance
  • PMD converter — paste a PMD XML rule file and get an ESLint config snippet in the browser

Installation

npm install --save-dev eslint-plugin-apex

Requires ESLint v9+ and Node.js v18+.

Quick Start

// eslint.config.js
import apex from 'eslint-plugin-apex';

export default [apex.configs.recommended];

Available Configs

ConfigSeverityDescription
apex.configs.recommendederrors for problem rules, warnings for suggestionRecommended set of rules
apex.configs.stricterror for allEvery rule enabled as an error
apex.configs.securityerrorSecurity rules only
apex.configs.performanceerrorPerformance rules only

All configs automatically target **/*.cls, **/*.trigger, and **/*.apex files.

Manual Rule Configuration

// eslint.config.js
import apex from 'eslint-plugin-apex';

export default [
  {
    files: ['**/*.cls', '**/*.trigger', '**/*.apex'],
    plugins: { apex },
    languageOptions: apex.configs.recommended.languageOptions,
    rules: {
      'apex/security-no-soql-injection': 'error',
      'apex/perf-no-dml-in-loop': 'error',
      'apex/best-test-has-asserts': 'warn',
      // disable a rule
      'apex/doc-require-apexdoc': 'off',
    },
  },
];

Rule Reference

Default reflects apex.configs.recommended: problem + recommended: trueerror; suggestion + recommended: truewarn; recommended: falseoff.

Best Practices

RuleDescriptionPMD equivalentDefault
apex/best-debug-use-logging-levelSystem.debug() calls should specify a LoggingLevel argumentDebugsShouldUseLoggingLevelwarn
apex/best-no-future-annotationPrefer Queueable over @Future — the future annotation has significant limitationsAvoidFutureAnnotationoff
apex/best-no-global-modifierAvoid 'global' class modifier — it permanently locks the public API in managed packagesAvoidGlobalModifierwarn
apex/best-no-logic-in-triggerAvoid placing business logic directly in triggers — delegate to handler classesAvoidLogicInTriggerwarn
apex/best-no-unused-local-variableDetects local variables that are declared but never readUnusedLocalVariableoff
apex/best-queueable-needs-finalizerQueueable classes should attach a Finalizer for error recoveryQueueableWithoutFinalizer (+ legacy QueueableShouldAttachFinalizer)off
apex/best-test-assertions-have-messageSystem.assert() calls should include a message parameter for clarityApexAssertionsShouldIncludeMessagewarn
apex/best-test-has-assertsApex unit test classes should include at least one assertionApexUnitTestClassShouldHaveAssertswarn
apex/best-test-has-run-asTest classes should include at least one System.runAs() callApexUnitTestClassShouldHaveRunAswarn
apex/best-test-method-annotationUse @IsTest annotation instead of the deprecated 'testMethod' keywordApexUnitTestMethodShouldHaveIsTestAnnotationwarn
apex/best-test-no-see-all-dataAvoid @isTest(seeAllData=true) as it exposes real org data to test modificationsApexUnitTestShouldNotUseSeeAllDataTrueerror

Code Style

RuleDescriptionPMD equivalentDefault
apex/style-annotation-namingAnnotation names should use PascalCaseAnnotationsNamingConventionswarn
apex/style-braces-for-forRequire braces around for loop bodiesForLoopsMustUseBraceswarn
apex/style-braces-for-ifRequire braces around if/else statement bodiesIfStmtsMustUseBraces / IfElseStmtsMustUseBraceswarn
apex/style-braces-for-whileRequire braces around while loop bodiesWhileLoopsMustUseBraceswarn
apex/style-fields-at-startField declarations should appear before method declarationsFieldDeclarationsShouldBeAtStartwarn
apex/style-naming-conventionsEnforce configurable naming conventions for Apex declarationsClassNamingConventions / MethodNamingConventions / FieldNamingConventions / LocalVariableNamingConventions / FormalParameterNamingConventions / PropertyNamingConventionswarn
apex/style-one-declaration-per-lineDeclare only one variable per statementOneDeclarationPerLinewarn

Design

RuleDescriptionPMD equivalentDefault
apex/design-cognitive-complexityLimit cognitive complexity of methods and classesCognitiveComplexitywarn
apex/design-cyclomatic-complexityLimit cyclomatic complexity of methods and classesCyclomaticComplexity / StdCyclomaticComplexitywarn
apex/design-excessive-parametersFlag methods with too many parametersExcessiveParameterListwarn
apex/design-excessive-public-countFlag classes with too many public methods or attributesExcessivePublicCountwarn
apex/design-ncss-method-countLimit the number of non-commenting source statements per method and classNcssMethodCount / NcssCount / NcssTypeCountwarn
apex/design-no-boolean-parametersAvoid boolean parameters in public and global methodsAvoidBooleanMethodParameterswarn
apex/design-no-deep-nestingAvoid deeply nested if statementsAvoidDeeplyNestedIfStmtswarn
apex/design-no-unused-methodDetect private methods that are never called within the classUnusedMethodoff
apex/design-too-many-fieldsFlag classes with too many fieldsTooManyFieldswarn

Documentation

RuleDescriptionPMD equivalentDefault
apex/doc-require-apexdocRequire ApexDoc comments on public and global classes, methods, and propertiesApexDocoff

Error Prone

RuleDescriptionPMD equivalentDefault
apex/error-aura-enabled-getter-public@AuraEnabled property getters must be public or globalInaccessibleAuraEnabledGetter (older docs sometimes mis-labeled this as AuraEnabledWithoutCatchBlock)error
apex/error-no-csrf-in-constructorDisallow DML operations in constructors or class initializersApexCSRFerror
apex/error-no-direct-trigger-map-accessAvoid direct index access to Trigger.new or Trigger.old — iterate insteadAvoidDirectAccessTriggerMaperror
apex/error-no-empty-catchDisallow empty catch blocksEmptyCatchBlockerror
apex/error-no-empty-ifDisallow empty if statement bodiesEmptyIfStmterror
apex/error-no-empty-tryDisallow empty try or finally blocksEmptyTryOrFinallyBlockerror
apex/error-no-empty-whileDisallow empty while loop bodiesEmptyWhileStmterror
apex/error-no-hardcoded-idAvoid hardcoding Salesforce record IDs — they differ between environmentsAvoidHardcodingIderror
apex/error-no-method-name-as-classNon-constructor methods should not share the name of the enclosing classMethodWithSameNameAsEnclosingClasserror
apex/error-no-nonexistent-annotationAvoid annotations that do not exist in ApexAvoidNonExistentAnnotations (+ legacy NonExistentCustomSettingOrMetadata)error
apex/error-no-stateful-db-resultAvoid storing Database result types as instance variables in Database.Stateful batch classesAvoidStatefulDatabaseResultoff
apex/error-no-type-shadow-namespaceAvoid declaring types with the same name as System or Schema namespace typesTypeShadowsBuiltInNamespace (+ legacy AvoidShadowingField)off
apex/error-override-both-equals-hashcodeIf overriding equals(), also override hashCode(), and vice versaOverrideBothEqualsAndHashcodeerror
apex/error-test-methods-in-test-class@IsTest methods must reside in @IsTest annotated classesTestMethodsMustBeInTestClasseserror

Performance

RuleDescriptionPMD equivalentDefault
apex/perf-no-debug-statementsRemove or gate System.debug() calls in production codeAvoidDebugStatementsoff
apex/perf-no-dml-in-loopAvoid DML operations, SOQL queries, and governor-limited calls inside loopsOperationWithLimitsInLoop (+ legacy AvoidDmlStatementsInLoops)error
apex/perf-no-eager-describeAvoid calling Schema.describe*() methods inside loops — cache results insteadAvoidEagerDescribes (distinct from EagerlyLoadedDescribeSObjectResult)error
apex/perf-no-high-cost-in-loopAvoid high-cost Apex calls inside loopsOperationWithHighCostInLoop (+ legacy AvoidSoqlInLoops / AvoidHighCostInLoopWithoutBulkification)error
apex/perf-no-non-restrictive-querySOQL queries should include a WHERE clause to limit resultsAvoidNonRestrictiveQueries (+ legacy WherelessSOQLQuery)error

Security

RuleDescriptionPMD equivalentDefault
apex/security-crud-violationDML operations and SOQL queries should include CRUD/FLS permission checksApexCRUDViolationwarn
apex/security-no-dangerous-methodsFlag potentially dangerous Apex method callsApexDangerousMethodswarn
apex/security-no-hardcoded-cryptoAvoid hardcoded cryptographic keys or IVsApexBadCryptoerror
apex/security-no-insecure-endpointHTTP callout endpoints must use HTTPSApexInsecureEndpointerror
apex/security-no-open-redirectAvoid constructing PageReference from user-controlled inputApexOpenRedirecterror
apex/security-no-soql-injectionAvoid SOQL injection — use bind variables or String.escapeSingleQuotes()ApexSOQLInjectionerror
apex/security-no-xss-false-escapeDisabling HTML escaping (escape=false) can introduce XSS vulnerabilitiesApexXSSFromEscapeFalseerror
apex/security-no-xss-from-urlURL parameter values must be sanitized before output to prevent XSSApexXSSFromURLParamerror
apex/security-sharing-violationsClasses that access data should explicitly declare 'with sharing' or 'without sharing'ApexSharingViolationswarn
apex/security-use-named-credentialsUse Named Credentials instead of hardcoding authentication details in HTTP requestsApexSuggestUsingNamedCredwarn

PMD Converter

The PMD Converter is a browser-based tool that converts PMD Apex XML rule files into:

  • An ESLint flat-config snippet with the correct rule IDs and severities
  • A rule implementation skeleton (when the PMD rule is not yet in this plugin)

No data is sent anywhere — conversion happens entirely in the browser.

PMD rules in the reference mirror without an ESLint twin (yet)

The offline PMD rule list this project tracks includes ExcessiveClassLength, EmptyStatementBlock, EagerlyLoadedDescribeSObjectResult, and NcssConstructorCount. They are intentionally not mapped to an apex/* rule today; the converter emits a custom-… skeleton for them. See the per-rule notes for perf-no-eager-describe versus EagerlyLoadedDescribeSObjectResult, and design-ncss-method-count versus per-constructor NCSS.

Architecture

eslint-plugin-apex/
├── src/
│   ├── node-types.js       ← custom AST node type constants + VISITOR_KEYS
│   ├── ast-builder.js      ← ANTLR4 parse tree → custom ESLint AST
│   ├── apex-parser.js      ← parseForESLint() adapter
│   ├── index.js            ← plugin entry point, rule registry, shared configs
│   └── rules/
│       ├── best-practices/ ← 11 rules
│       ├── code-style/     ← 7 rules
│       ├── design/         ← 9 rules
│       ├── documentation/  ← 1 rule
│       ├── error-prone/    ← 14 rules
│       ├── performance/    ← 5 rules
│       └── security/       ← 10 rules
├── tests/
│   ├── parser.test.js      ← custom parser tests (node:test)
│   ├── rules.test.js       ← RuleTester tests for all rules
│   └── docs-coverage.test.js
└── docs/
    ├── index.html          ← GitHub Pages PMD converter
    └── rules/              ← one Markdown page per registered rule
        ├── best-practices/
        ├── code-style/
        ├── design/
        ├── documentation/
        ├── error-prone/
        ├── performance/
        └── security/

The parser uses @apexdevtools/apex-parser, an ANTLR4-based Apex parser, and wraps its concrete syntax tree into a flat, traversable AST with custom node types.

Contributing

Contributions welcome — especially:

  • Improved AST coverage for edge-case Apex constructs
  • More comprehensive rule implementations
  • Additional test cases

License

MIT — see LICENSE.

Keywords

eslint

FAQs

Package last updated on 10 Apr 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts