{"id":13138,"library":"eslint-ast-utils","title":"ESLint AST Utilities","description":"eslint-ast-utils is a utility library designed to simplify common Abstract Syntax Tree (AST) manipulations specifically for ESLint rule development. It provides helper functions to analyze AST nodes, such as identifying CommonJS `require()` calls, extracting their sources, checking for variable references within a node's scope, and safely getting property names from `MemberExpression` nodes. The current stable version is 1.1.0, released in 2017. The project appears to be in maintenance mode, with infrequent updates since its last major release. Its primary differentiation lies in providing pre-built checks for patterns frequently encountered when writing custom ESLint rules, abstracting some of the complexities of direct ESTree traversal.","status":"maintenance","version":"1.1.0","language":"javascript","source_language":"en","source_url":"https://github.com/jfmengels/eslint-ast-utils","tags":["javascript","eslint","ast","utils","Utility"],"install":[{"cmd":"npm install eslint-ast-utils","lang":"bash","label":"npm"},{"cmd":"yarn add eslint-ast-utils","lang":"bash","label":"yarn"},{"cmd":"pnpm add eslint-ast-utils","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"This library is primarily CommonJS. While some bundlers or Node.js versions with specific configurations might allow `import astUtils from 'eslint-ast-utils';`, direct usage in Node.js ESM projects typically requires a CommonJS wrapper or dynamic `import()` for reliable interoperability.","wrong":"import astUtils from 'eslint-ast-utils';","symbol":"astUtils","correct":"const astUtils = require('eslint-ast-utils');"},{"note":"The library exports an object containing utility functions as its `module.exports`. Therefore, individual functions like `isStaticRequire` can be destructured directly from the `require()` call in CommonJS. However, using a named import syntax like `import { isStaticRequire }` in an ESM context will fail because `isStaticRequire` is not a top-level named export.","wrong":"import { isStaticRequire } from 'eslint-ast-utils';","symbol":"isStaticRequire","correct":"const { isStaticRequire } = require('eslint-ast-utils');"},{"note":"Similar to other utilities, `getPropertyName` is a property of the object exported by the module. It must be accessed via the imported object (`astUtils.getPropertyName`) or by destructuring the object in CommonJS. Direct named ESM imports are not supported.","wrong":"import { getPropertyName } from 'eslint-ast-utils';","symbol":"getPropertyName","correct":"const astUtils = require('eslint-ast-utils');\n// ... later ...\nastUtils.getPropertyName(node);"}],"quickstart":{"code":"const astUtils = require('eslint-ast-utils');\nconst espree = require('espree'); // A common AST parser for examples\n\nconst code = `\n  // Example code to parse\n  const myVar = require('lodash');\n  function processData(input) {\n    if (astUtils.containsIdentifier('input', input)) { // Self-referential check example\n        const result = input.value;\n        console.log(result);\n    }\n    return myVar.isString(input);\n  }\n  require('./another-module');\n`;\n\nconst ast = espree.parse(code, { ecmaVersion: 2018, loc: true, range: true });\n\n// A basic visitor pattern to find nodes of interest\nfunction traverse(node, visitor) {\n  if (!node || typeof node !== 'object') return;\n  visitor(node);\n  for (const key in node) {\n    if (node[key] && typeof node[key] === 'object') {\n      if (Array.isArray(node[key])) {\n        node[key].forEach(item => traverse(item, visitor));\n      } else {\n        traverse(node[key], visitor);\n      }\n    }\n  }\n}\n\ntraverse(ast, (node) => {\n  if (node.type === 'CallExpression' && astUtils.isStaticRequire(node)) {\n    console.log(`Found static require: '${astUtils.getRequireSource(node)}' at line ${node.loc.start.line}`);\n  }\n  if (node.type === 'MemberExpression') {\n    const propertyName = astUtils.getPropertyName(node);\n    if (propertyName !== undefined) {\n      console.log(`Found member expression property: '${propertyName}' at line ${node.loc.start.line}`);\n    }\n  }\n});\n\n// Note: To run this example, install espree: npm install espree","lang":"javascript","description":"This quickstart demonstrates parsing a JavaScript code snippet into an AST using 'espree' and then traversing the AST to identify static `require` calls and extract property names from `MemberExpression` nodes, showcasing typical use cases for `eslint-ast-utils` in an ESLint rule context."},"warnings":[{"fix":"For ESM projects, use dynamic `import()` or a CommonJS wrapper. Example: `const astUtils = await import('eslint-ast-utils');` or create a `.cjs` file to `require()` and then re-export.","message":"This library is written exclusively in CommonJS (CJS). Direct usage in modern Node.js environments configured for ECMAScript Modules (ESM) (e.g., with `\"type\": \"module\"` in `package.json` or a `.mjs` file) may require specific interop patterns or bundler configurations, as standard named ESM imports will not work without a transpilation step.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Thoroughly test its behavior with ASTs generated from modern JavaScript syntax. Consider alternatives or custom AST traversal logic for full support of the latest ECMAScript features or direct ESLint-provided utilities.","message":"The package has not seen significant updates since its 1.1.0 release in 2017. While core AST structures for JavaScript remain stable, newer ECMAScript features (e.g., optional chaining, nullish coalescing, private class fields) or changes in ESLint's own AST representations (ESTree) might not be fully supported or handled by these utilities.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Refer to the documentation for `containsIdentifier` and thoroughly test scenarios with nested scopes and shadowed variables to ensure it behaves as expected for your specific rule logic. Consider using ESLint's `ScopeManager` for more robust scope analysis if needed.","message":"The `containsIdentifier` function includes nuanced scoping logic to avoid false positives for shadowed variables, but its exact behavior might require careful testing in complex scenarios. Incorrect assumptions about its behavior can lead to faulty ESLint rules that misidentify unused variables or incorrect references.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"In an ESM context, use a dynamic `import()`: `const astUtilsModule = await import('eslint-ast-utils'); const astUtils = astUtilsModule.default || astUtilsModule;`. Alternatively, if possible, switch the file to CommonJS (`.cjs` extension or remove `\"type\": \"module\"` from `package.json`).","cause":"Attempting to use `require()` in a Node.js ESM module (e.g., a file with `\"type\": \"module\"` in `package.json` or a `.mjs` file). ESM modules do not have a global `require` function by default.","error":"ReferenceError: require is not defined"},{"fix":"Import the entire module as a default object and access its properties: `import astUtils from 'eslint-ast-utils'; astUtils.isStaticRequire(node);`. For TypeScript, you might need `import astUtils = require('eslint-ast-utils');` or `import * as astUtils from 'eslint-ast-utils';` with `esModuleInterop: true`.","cause":"This typically occurs when trying to use named ESM imports like `import { isStaticRequire } from 'eslint-ast-utils';` on a CommonJS module that exports an object as its `module.exports`. CommonJS exports are treated as a single default export in ESM.","error":"TypeError: (0, _eslintAstUtils.isStaticRequire) is not a function"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":""}