Comprehensive set of 17 ESLint rules for enforcing JavaScript promise best practices, covering error handling, return statements, nesting, callback integration, and parameter validation.
Rules that enforce fundamental promise patterns and prevent common mistakes.
Require returning inside each then() to create readable and reusable Promise chains.
/**
* ESLint rule: Require returning inside each then() callback
* @type {ESLintRule}
* @severity error (in recommended config)
*/
const alwaysReturnRule = {
meta: {
type: 'problem',
docs: {
description: 'Require returning inside each `then()` to create readable and reusable Promise chains.',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/always-return.md'
},
schema: [{
type: 'object',
properties: {
ignoreLastCallback: { type: 'boolean' },
ignoreAssignmentVariable: {
type: 'array',
items: { type: 'string', pattern: '^[\\w$]+$' },
uniqueItems: true
}
},
additionalProperties: false
}],
messages: {
alwaysReturn: 'Promise should be returned inside each then() callback'
}
},
create(context) { /* rule implementation */ }
};Configuration Options:
{
"promise/always-return": ["error", {
"ignoreLastCallback": false,
"ignoreAssignmentVariable": ["result", "data"]
}]
}ignoreLastCallback (boolean): When true, ignores the last callback in a chainignoreAssignmentVariable (array): Variable names to ignore when assigned promise valuesEnforce the use of catch() on un-returned promises.
/**
* ESLint rule: Enforce catch() on un-returned promises
* @type {ESLintRule}
* @severity error (in recommended config)
*/
const catchOrReturnRule = {
meta: {
type: 'problem',
docs: {
description: 'Enforce the use of `catch()` on un-returned promises.',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/catch-or-return.md'
},
schema: [{
type: 'object',
properties: {
allowFinally: { type: 'boolean' },
allowThen: { type: 'boolean' },
allowThenStrict: { type: 'boolean' },
terminationMethod: {
oneOf: [
{ type: 'string' },
{ type: 'array', items: { type: 'string' } }
]
}
},
additionalProperties: false
}],
messages: {
terminationMethod: 'Promise should be returned or have a catch handler'
}
},
create(context) { /* rule implementation */ }
};Configuration Options:
{
"promise/catch-or-return": ["error", {
"allowFinally": false,
"allowThen": false,
"allowThenStrict": false,
"terminationMethod": ["catch", "finally"]
}]
}allowFinally (boolean): Allow using .finally() without catchallowThen (boolean): Allow using .then() without catchallowThenStrict (boolean): Strict mode for then usageterminationMethod (string|array): Allowed termination methodsEnforce consistent param names and ordering when creating new promises.
/**
* ESLint rule: Enforce consistent promise constructor parameter names
* @type {ESLintRule}
* @severity error (in recommended config)
*/
const paramNamesRule = {
meta: {
type: 'suggestion',
docs: {
description: 'Enforce consistent param names and ordering when creating new promises.',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/param-names.md'
},
schema: [{
type: 'object',
properties: {
resolvePattern: { type: 'string' },
rejectPattern: { type: 'string' }
},
additionalProperties: false
}],
messages: {
resolveParamNames: 'Promise constructor parameters must be named to match "{{ resolvePattern }}"',
rejectParamNames: 'Promise constructor parameters must be named to match "{{ rejectPattern }}"'
}
},
create(context) { /* rule implementation */ }
};Configuration Options:
{
"promise/param-names": ["error", {
"resolvePattern": "^_?resolve$",
"rejectPattern": "^_?reject$"
}]
}resolvePattern (string): Regex pattern for resolve parameter name (default: "^_?resolve$")rejectPattern (string): Regex pattern for reject parameter name (default: "^_?reject$")Disallow wrapping values in Promise.resolve or Promise.reject when not needed.
/**
* ESLint rule: Disallow unnecessary Promise wrapping
* @type {ESLintRule}
* @severity error (in recommended config)
*/
const noReturnWrapRule = {
meta: {
type: 'suggestion',
docs: {
description: 'Disallow wrapping values in `Promise.resolve` or `Promise.reject` when not needed.',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/no-return-wrap.md'
},
schema: [{
type: 'object',
properties: {
allowReject: { type: 'boolean' }
},
additionalProperties: false
}],
messages: {
resolve: 'Avoid wrapping return values in Promise.resolve',
reject: 'Avoid wrapping return values in Promise.reject'
}
},
create(context) { /* rule implementation */ }
};Configuration Options:
{
"promise/no-return-wrap": ["error", {
"allowReject": false
}]
}allowReject (boolean): When true, allows wrapping return values in Promise.rejectRules that prevent dangerous or error-prone promise patterns.
Disallow calling new on a Promise static method.
/**
* ESLint rule: Disallow new on Promise static methods
* @type {ESLintRule}
* @severity error (in recommended config)
* @fixable code
*/
const noNewStaticsRule = {
meta: {
type: 'problem',
docs: {
description: 'Disallow calling `new` on a Promise static method.',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/no-new-statics.md'
},
fixable: 'code',
schema: [],
messages: {
avoidNewStatic: "Avoid calling 'new' on 'Promise.{{ name }}()'"
}
},
create(context) { /* rule implementation with auto-fix */ }
};Disallow creating new promises with paths that resolve multiple times.
/**
* ESLint rule: Disallow multiple promise resolution
* @type {ESLintRule}
* @severity not in recommended config
*/
const noMultipleResolvedRule = {
meta: {
type: 'problem',
docs: {
description: 'Disallow creating new promises with paths that resolve multiple times.',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/no-multiple-resolved.md'
},
schema: [],
messages: {
multipleResolvers: 'Promise constructor contains multiple calls to resolve/reject'
}
},
create(context) { /* rule implementation */ }
};Enforces the proper number of arguments are passed to Promise functions.
/**
* ESLint rule: Validate Promise function parameters
* @type {ESLintRule}
* @severity warn (in recommended config)
*/
const validParamsRule = {
meta: {
type: 'problem',
docs: {
description: 'Enforces the proper number of arguments are passed to Promise functions.',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/valid-params.md'
},
schema: [{
type: 'object',
properties: {
exclude: {
type: 'array',
items: { type: 'string' }
}
},
additionalProperties: false
}],
messages: {
invalidParams: 'Promise method called with incorrect number of arguments'
}
},
create(context) { /* rule implementation */ }
};Configuration Options:
{
"promise/valid-params": ["warn", {
"exclude": ["done", "next"]
}]
}exclude (array): Array of method names to exclude from validationRules that enforce consistent promise coding style and patterns.
Disallow nested then() or catch() statements.
/**
* ESLint rule: Disallow nested promise chains
* @type {ESLintRule}
* @severity warn (in recommended config)
*/
const noNestingRule = {
meta: {
type: 'suggestion',
docs: {
description: 'Disallow nested `then()` or `catch()` statements.',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/no-nesting.md'
},
schema: [],
messages: {
nesting: 'Avoid nesting promises'
}
},
create(context) { /* rule implementation */ }
};Disallow return statements in finally().
/**
* ESLint rule: Disallow return in finally blocks
* @type {ESLintRule}
* @severity warn (in recommended config)
*/
const noReturnInFinallyRule = {
meta: {
type: 'problem',
docs: {
description: 'Disallow return statements in `finally()`.',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/no-return-in-finally.md'
},
schema: [],
messages: {
returnsInFinally: 'No return statement should be used in finally block'
}
},
create(context) { /* rule implementation */ }
};Prefer catch to then(a, b)/then(null, b) for handling errors.
/**
* ESLint rule: Prefer catch over then error handling
* @type {ESLintRule}
* @severity not in recommended config
* @fixable code
*/
const preferCatchRule = {
meta: {
type: 'suggestion',
docs: {
description: 'Prefer `catch` to `then(a, b)`/`then(null, b)` for handling errors.',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/prefer-catch.md'
},
fixable: 'code',
schema: [],
messages: {
preferCatch: 'Prefer catch() over then() with second parameter'
}
},
create(context) { /* rule implementation with auto-fix */ }
};Rules for managing interaction between promises and callbacks.
Disallow calling cb() inside of a then().
/**
* ESLint rule: Disallow callbacks inside promises
* @type {ESLintRule}
* @severity warn (in recommended config)
*/
const noCallbackInPromiseRule = {
meta: {
type: 'suggestion',
docs: {
description: 'Disallow calling `cb()` inside of a `then()` (use [util.callbackify][] instead).',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/no-callback-in-promise.md'
},
schema: [{
type: 'object',
properties: {
exceptions: {
type: 'array',
items: { type: 'string' }
},
timeoutsErr: { type: 'boolean' }
},
additionalProperties: false
}],
messages: {
callback: 'Avoid calling callback functions inside promises'
}
},
create(context) { /* rule implementation */ }
};Configuration Options:
{
"promise/no-callback-in-promise": ["warn", {
"exceptions": ["done", "next"],
"timeoutsErr": false
}]
}exceptions (array): Array of callback names to exclude from the ruletimeoutsErr (boolean): Whether to treat timeout functions as errorsDisallow using promises inside of callbacks.
/**
* ESLint rule: Disallow promises inside callbacks
* @type {ESLintRule}
* @severity warn (in recommended config)
*/
const noPromiseInCallbackRule = {
meta: {
type: 'suggestion',
docs: {
description: 'Disallow using promises inside of callbacks.',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/no-promise-in-callback.md'
},
schema: [],
messages: {
promise: 'Avoid using promises inside callbacks'
}
},
create(context) { /* rule implementation */ }
};Rules for async/await patterns and modern promise usage.
Prefer await to then()/catch()/finally() for reading Promise values.
/**
* ESLint rule: Prefer await over then/catch/finally
* @type {ESLintRule}
* @severity not in recommended config
*/
const preferAwaitToThenRule = {
meta: {
type: 'suggestion',
docs: {
description: 'Prefer `await` to `then()`/`catch()`/`finally()` for reading Promise values.',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/prefer-await-to-then.md'
},
schema: [{
type: 'object',
properties: {
strict: { type: 'boolean' }
},
additionalProperties: false
}],
messages: {
preferAwait: 'Prefer await to then()'
}
},
create(context) { /* rule implementation */ }
};Configuration Options:
{
"promise/prefer-await-to-then": ["error", {
"strict": false
}]
}strict (boolean): When true, enforces strict mode for await usagePrefer async/await to the callback pattern.
/**
* ESLint rule: Prefer async/await over callbacks
* @type {ESLintRule}
* @severity not in recommended config
*/
const preferAwaitToCallbacksRule = {
meta: {
type: 'suggestion',
docs: {
description: 'Prefer `async`/`await` to the callback pattern.',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/prefer-await-to-callbacks.md'
},
schema: [],
messages: {
preferAsync: 'Prefer async/await over callback patterns'
}
},
create(context) { /* rule implementation */ }
};Rules for handling different JavaScript environments and promise implementations.
Require creating a Promise constructor before using it in an ES5 environment.
/**
* ESLint rule: Require Promise constructor in ES5
* @type {ESLintRule}
* @severity off (in recommended config)
*/
const noNativeRule = {
meta: {
type: 'suggestion',
docs: {
description: 'Require creating a `Promise` constructor before using it in an ES5 environment.',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/no-native.md'
},
schema: [],
messages: {
native: 'Native Promise constructor not available in ES5'
}
},
create(context) { /* rule implementation */ }
};Disallow creating new promises outside of utility libs.
/**
* ESLint rule: Disallow new Promise outside utilities
* @type {ESLintRule}
* @severity off (in recommended config)
*/
const avoidNewRule = {
meta: {
type: 'suggestion',
docs: {
description: 'Disallow creating `new` promises outside of utility libs (use [util.promisify][] instead).',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/avoid-new.md'
},
schema: [],
messages: {
avoidNew: 'Avoid creating new promises outside utility functions'
}
},
create(context) { /* rule implementation */ }
};Disallow use of non-standard Promise static methods.
/**
* ESLint rule: Disallow non-standard Promise methods
* @type {ESLintRule}
* @severity not in recommended config
*/
const specOnlyRule = {
meta: {
type: 'suggestion',
docs: {
description: 'Disallow use of non-standard Promise static methods.',
url: 'https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/spec-only.md'
},
schema: [{
type: 'object',
properties: {
allowedMethods: {
type: 'array',
items: { type: 'string' }
}
},
additionalProperties: false
}],
messages: {
nonStandard: 'Non-standard Promise method not allowed'
}
},
create(context) { /* rule implementation */ }
};Configuration Options:
{
"promise/spec-only": ["error", {
"allowedMethods": ["delay", "timeout"]
}]
}allowedMethods (array): Array of non-standard method names to allowThese rules are enabled in the recommended configuration:
always-return (error): Require return statements in then() callbackscatch-or-return (error): Require catch() on un-returned promisesparam-names (error): Enforce consistent promise constructor parametersno-return-wrap (error): Avoid unnecessary Promise.resolve/reject wrappingno-new-statics (error): Disallow new on Promise static methodsno-nesting (warn): Avoid nested promise chainsno-callback-in-promise (warn): Avoid callbacks inside promisesno-promise-in-callback (warn): Avoid promises inside callbacksno-return-in-finally (warn): Disallow return in finally blocksvalid-params (warn): Validate Promise function parametersThese rules are available but not enabled by default:
prefer-await-to-then: Prefer await over then/catch/finallyprefer-await-to-callbacks: Prefer async/await over callbacksprefer-catch: Prefer catch() over then() error handlingno-multiple-resolved: Disallow multiple promise resolutionspec-only: Disallow non-standard Promise methodsThese rules are disabled in the recommended configuration:
no-native: Allow native Promise constructor usageavoid-new: Allow new Promise() constructioninterface ESLintRule {
meta: {
type: 'problem' | 'suggestion' | 'layout';
docs: {
description: string;
url: string;
};
fixable?: 'code' | 'whitespace';
schema: any[];
messages: { [messageId: string]: string };
};
create(context: ESLintContext): ESLintVisitor;
}
interface ESLintContext {
report(descriptor: ReportDescriptor): void;
getSourceCode(): SourceCode;
getFilename(): string;
getScope(): Scope;
}
interface ReportDescriptor {
node: ESTreeNode;
messageId: string;
data?: { [key: string]: string };
fix?(fixer: RuleFixer): Fix;
}
interface ESLintVisitor {
[nodeType: string]: (node: ESTreeNode) => void;
}