{"id":11193,"library":"jsx-ast-utils","title":"JSX AST Utilities","description":"jsx-ast-utils is a dedicated utility module designed for the static analysis of JSX Abstract Syntax Tree (AST) nodes. It provides functions to query, validate, and extract information from JSX elements, particularly focusing on prop existence and values. Currently stable at version 3.3.5, it offers a consistent API for working with JSX ASTs, making it an invaluable tool for authors of linting rules, code transformers, or other static analysis tools. Originally extracted from eslint-plugin-jsx-a11y, its primary differentiator is its focused scope on JSX syntax, providing robust and tested utilities that account for various JSX complexities including spread attributes and case insensitivity.","status":"active","version":"3.3.5","language":"javascript","source_language":"en","source_url":"https://github.com/jsx-eslint/jsx-ast-utils","tags":["javascript","jsx","ast","lint","eslint"],"install":[{"cmd":"npm install jsx-ast-utils","lang":"bash","label":"npm"},{"cmd":"yarn add jsx-ast-utils","lang":"bash","label":"yarn"},{"cmd":"pnpm add jsx-ast-utils","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Primary ESM named import for checking prop existence. For CommonJS, use `const { hasProp } = require('jsx-ast-utils');`","wrong":"const hasProp = require('jsx-ast-utils'); // Missing .hasProp after require","symbol":"hasProp","correct":"import { hasProp } from 'jsx-ast-utils';"},{"note":"Retrieves the full JSXAttribute node or `undefined`. Use named import for both ESM and CommonJS.","wrong":"const getProp = require('jsx-ast-utils/getProp'); // Direct file imports are discouraged and may break","symbol":"getProp","correct":"import { getProp } from 'jsx-ast-utils';"},{"note":"Checks if any of the provided props exist on a JSX element. Always use named imports for top-level utilities.","wrong":"import hasAnyProp from 'jsx-ast-utils'; // No default export from the main package","symbol":"hasAnyProp","correct":"import { hasAnyProp } from 'jsx-ast-utils';"}],"quickstart":{"code":"import { hasProp } from 'jsx-ast-utils';\n\n// This example mimics an ESLint rule structure to demonstrate usage.\n// In a real ESLint rule, `context` and `node` would be provided by ESLint.\nconst mockContext = {\n  report: ({ node, message }) => console.log(`Report at node ${node.type}: ${message}`)\n};\n\nconst mockJSXOpeningElementNode = {\n  type: 'JSXOpeningElement',\n  attributes: [\n    { type: 'JSXAttribute', name: { type: 'JSXIdentifier', name: 'id' }, value: null },\n    { type: 'JSXAttribute', name: { type: 'JSXIdentifier', name: 'className' }, value: null },\n    { type: 'JSXSpreadAttribute', argument: { type: 'Identifier', name: 'props' } }\n  ]\n};\n\n// Example usage within a mock ESLint rule visitor\nfunction JSXOpeningElementVisitor(node, context) {\n  const hasIdProp = hasProp(node.attributes, 'id');\n  const hasOnChange = hasProp(node.attributes, 'onChange', { spreadStrict: false }); // Look within spreads\n  const hasDataAttr = hasProp(node.attributes, 'data-testId', { ignoreCase: true }); // Case-insensitive search\n\n  if (!hasIdProp) {\n    context.report({ node, message: `JSX element is missing 'id' prop.` });\n  }\n\n  if (hasOnChange) {\n    context.report({ node, message: `JSX element has an 'onChange' prop, which might be a concern.` });\n  }\n\n  if (hasDataAttr) {\n    context.report({ node, message: `JSX element has a data-testid attribute.` });\n  }\n}\n\n// Simulate ESLint calling the visitor\nJSXOpeningElementVisitor(mockJSXOpeningElementNode, mockContext);","lang":"javascript","description":"Demonstrates how to use `hasProp` within a simplified ESLint-like visitor function to check for prop existence on JSX elements, including handling spread attributes and case insensitivity."},"warnings":[{"fix":"Review any code that interacts with `getProp` or related utilities to ensure it correctly handles the guaranteed return of a value, even if the prop is not found or malformed. Adjust checks from `if (!prop)` to `if (prop === undefined)` if strict non-existence handling is needed.","message":"In `v2.0.0`, the internal `propName` utility (and consequently functions like `getProp`) was changed to always return a value, where previously it might have returned `undefined` or thrown an error for certain cases. If your code relied on this previous behavior, it constitutes a breaking change.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"To correctly check for props that might be included through spread attributes, explicitly set `spreadStrict: false` in the options object: `hasProp(attributes, 'myProp', { spreadStrict: false })`.","message":"The `hasProp`, `hasAnyProp`, and `hasEveryProp` utilities default `spreadStrict` to `true`. This means if a prop is supplied via a JSX spread attribute (`{...props}`), the utility will report that the specific prop does NOT exist.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"If strict case-sensitive matching is required for a prop, you must implement a manual check. This can involve iterating through the `node.attributes` array and performing a case-sensitive comparison on `attribute.name.name`.","message":"The `hasProp`, `hasAnyProp`, and `hasEveryProp` utilities default `ignoreCase` to `true`. This means they will find a prop like 'onClick' if you search for 'onclick'.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Upgrade to `jsx-ast-utils@^2.1.0` or newer if working with TypeScript or TSX files to ensure proper AST node handling and prevent unexpected behavior.","message":"Support for TypeScript AST node types was officially added in `v2.1.0`. Older versions might not correctly parse or analyze TSX/TypeScript-specific AST nodes, leading to incorrect results or runtime errors when processing TypeScript codebases.","severity":"breaking","affected_versions":"<2.1.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Before accessing `node.attributes` or passing a node to `jsx-ast-utils` functions expecting JSX attributes, ensure that `node.type === 'JSXOpeningElement'` (or a similar check for relevant JSX node types).","cause":"This error occurs when attempting to access the `attributes` property on an AST node that is not a `JSXOpeningElement`. The `attributes` property is specific to JSX opening tags.","error":"TypeError: Cannot read properties of undefined (reading 'attributes')"},{"fix":"Switch to ESM import syntax: `import { hasProp } from 'jsx-ast-utils';` for named exports.","cause":"This typically happens when you are using CommonJS `require()` syntax within an ECMAScript module (ESM) environment (e.g., in a Node.js project with `\"type\": \"module\"` in `package.json` or in a modern browser context).","error":"ReferenceError: require is not defined in ES module scope"},{"fix":"For CommonJS, ensure you are correctly destructuring the named export: `const { hasProp } = require('jsx-ast-utils');`.","cause":"This error often indicates an incorrect import or destructuring when using CommonJS. Common mistakes include `require('jsx-ast-utils')` without subsequently accessing `.hasProp`, or attempting `require('jsx-ast-utils/hasProp')` assuming a default export from a subpath.","error":"TypeError: hasProp is not a function"}],"ecosystem":"npm"}