{"id":10700,"library":"cst","title":"JavaScript CST Implementation","description":"The `cst` package provides a Concrete Syntax Tree (CST) implementation for JavaScript, distinguishing itself from Abstract Syntax Trees (ASTs) by preserving all source code information, including whitespace, comments, and punctuation. This makes it particularly useful for applications requiring precise code transformation, refactoring, linting, and style enforcement, where original formatting must be maintained. The library aims for 100% compatibility with the ESTree AST specification, ensuring that its `Node` structures align with standard AST representations. A core principle is that the tree always remains valid, protecting against structural inconsistencies during modifications. The current stable version is 0.4.10, but its last publish date was over six years ago, indicating that it is in a maintenance state with no active development or new releases. Despite this, its core functionality for detailed source code representation and manipulation remains sound. Key differentiators include its complete representation of the source text, ESTree AST compatibility, and robust mutation methods designed to preserve code integrity and formatting.","status":"maintenance","version":"0.4.10","language":"javascript","source_language":"en","source_url":"https://github.com/cst/cst","tags":["javascript"],"install":[{"cmd":"npm install cst","lang":"bash","label":"npm"},{"cmd":"yarn add cst","lang":"bash","label":"yarn"},{"cmd":"pnpm add cst","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The primary function to convert a JavaScript string into a CST. Uses named export.","wrong":"const parse = require('cst').parse;","symbol":"parse","correct":"import { parse } from 'cst';"},{"note":"Represents AST-like structures within the CST, extending the base Element class. Used for type checking and structural traversal.","wrong":"import Node from 'cst';","symbol":"Node","correct":"import { Node } from 'cst';"},{"note":"Represents the atomic lexical units (like identifiers, operators, whitespace, comments) of the source code. Essential for fine-grained manipulation.","wrong":"import { CSTToken } from 'cst';","symbol":"Token","correct":"import { Token } from 'cst';"}],"quickstart":{"code":"import { parse, Token, Node } from 'cst';\n\nconst code = `\n  function greet(name) {\n    // Say hello to someone\n    console.log('Hello, ' + name + '!');\n  }\n  greet('World'); // We'll change this\n`;\n\n// Parse the code into a CST\nconst tree = parse(code);\n\nconsole.log('Original Code:\\n', tree.getSourceCode());\n\nlet worldToken: Token | undefined;\n\n// Find the 'World' string literal token\ntree.childElements.forEach(element => {\n  if (element.isNode && (element as Node).type === 'ExpressionStatement') {\n    const callExpr = element.childElements.find(c => c.isNode && (c as Node).type === 'CallExpression') as Node;\n    if (callExpr) {\n      const literalNode = callExpr.childElements.find(c => c.isNode && (c as Node).type === 'Literal') as Node;\n      if (literalNode) {\n        const tokenChild = literalNode.getFirstToken();\n        if (tokenChild && tokenChild.value === \"'World'\") {\n          worldToken = tokenChild;\n        }\n      }\n    }\n  }\n});\n\nif (worldToken) {\n  const parentOfWorldToken = worldToken.parentElement;\n  if (parentOfWorldToken) {\n    // Create a new token for 'CST User'\n    const newUserToken = new Token('String', \"'CST User'\");\n    // Replace the old token within its parent Node\n    parentOfWorldToken.replaceChildren(newUserToken, worldToken, worldToken);\n    console.log('\\nModified Code (Changed String Literal):\\n', tree.getSourceCode());\n  }\n} else {\n  console.log('\\nCould not find \"World\" token to modify.');\n}","lang":"typescript","description":"Demonstrates parsing JavaScript code into a CST, traversing the tree to find a specific string literal token, and then modifying that token's value while preserving surrounding whitespace and comments."},"warnings":[{"fix":"Update code to use standard JavaScript array/generator syntax or ensure input does not contain comprehensions.","message":"Support for JavaScript Comprehensions (an older, non-standardized feature) was removed. Code relying on parsing or manipulating comprehensions will break.","severity":"breaking","affected_versions":">=0.0.11"},{"fix":"Review any code that uses `Token.cloneElement` (or its inherited version) to ensure it behaves as expected after the fix.","message":"The `Token.cloneElement` method had a bug that was fixed in v0.0.11. If you were relying on specific (potentially incorrect) behavior of cloning tokens in older versions, this fix might subtly change outcomes.","severity":"gotcha","affected_versions":">=0.0.11"},{"fix":"Always use methods like `parent.replaceChildren(newElement, oldElementRef, oldElementRef)` to perform modifications, constructing new `Node` or `Token` instances as needed.","message":"CST modification primarily occurs by replacing `Element`s (Nodes or Tokens) within their parent's children. Direct modification of `value` properties on `Token` instances is not supported, as tokens are generally immutable. You must create a new `Token` and replace the old one.","severity":"gotcha","affected_versions":">=0.0.1"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure the input string is valid JavaScript code compatible with the parser's grammar (ES5/ES6+). Check the exact line and column indicated in the error message.","cause":"The input JavaScript string provided to `parse()` contains a syntax error or an unsupported language feature.","error":"SyntaxError: Unexpected token (X:Y)"},{"fix":"Verify that `someElement` is a `Node` and is the parent of the `Element`s you intend to replace. Ensure the parent element is part of a valid CST structure.","cause":"Attempting to call `replaceChildren` or similar mutation methods on an `Element` that does not support it (e.g., a `Token` which cannot have children, or an `Element` not yet attached to a tree).","error":"TypeError: someElement.replaceChildren is not a function"},{"fix":"Add error handling around `parse()` calls and null checks when traversing the CST, especially after operations that might return `undefined`.","cause":"This usually indicates that the `tree` object (or an `Element` within it) is `undefined` or `null`, potentially because `parse()` failed or a traversal path led to an invalid element.","error":"TypeError: Cannot read properties of undefined (reading 'getSourceCode')"}],"ecosystem":"npm"}