{"id":11163,"library":"jscodeshift","title":"jscodeshift","description":"jscodeshift is a powerful toolkit for automating code transformations (codemods) across JavaScript and TypeScript projects. It operates by parsing source code into an Abstract Syntax Tree (AST), allowing programmatic manipulation, and then printing the modified AST back into code. The current stable version is 17.3.0, released in early 2026. While lacking a fixed release cadence, the project is actively maintained, with frequent minor and patch updates primarily driven by `recast` dependency bumps to support new language features (e.g., recent TypeScript syntax) and address parsing quirks. A significant version jump from `v0.x` to `v17.0.0` occurred in August 2024, signaling its maturity rather than a traditional `1.0` release. Its core strength lies in its tight integration with `recast`, which excels at preserving original code formatting, comments, and whitespace, minimizing disruption to a codebase's aesthetics during large-scale refactors. It offers a robust CLI runner for applying transforms to files and an intuitive API for writing complex, style-preserving codemods.","status":"active","version":"17.3.0","language":"javascript","source_language":"en","source_url":"https://github.com/facebook/jscodeshift","tags":["javascript","codemod","recast","babel"],"install":[{"cmd":"npm install jscodeshift","lang":"bash","label":"npm"},{"cmd":"yarn add jscodeshift","lang":"bash","label":"yarn"},{"cmd":"pnpm add jscodeshift","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency, typically needed if your codemod or the files it processes rely on Babel's environment presets for parsing or transformation.","package":"@babel/preset-env","optional":true}],"imports":[{"note":"A jscodeshift transform file exports a default function. `fileInfo` contains the source code, `api` provides the `j` (jscodeshift AST builder) and `g` (recast utility) objects, and `options` holds CLI arguments passed to the transform.","symbol":"transformer","correct":"export default function transformer(fileInfo: FileInfo, api: API, options: Options): string | null { /* ... */ }"},{"note":"The jscodeshift API, aliased as `j`, is an instance of `recast.types.builders` and is provided as part of the `api` object within the transform function, not directly imported from the package root.","wrong":"import j from 'jscodeshift';","symbol":"j (jscodeshift API)","correct":"const j = api.j;"},{"note":"Utilities for testing codemods, such as `runTransform`, are exposed from the `jscodeshift/testUtils` subpath rather than directly from the main package entry point.","wrong":"import { runTransform } from 'jscodeshift';","symbol":"runTransform","correct":"import { runTransform } from 'jscodeshift/testUtils';"},{"note":"For TypeScript projects, it is best practice to import these types using `import type` to clearly distinguish them from runtime values and prevent potential bundling issues.","wrong":"import { API, FileInfo, Options } from 'jscodeshift';","symbol":"FileInfo, API, Options (types)","correct":"import type { API, FileInfo, Options } from 'jscodeshift';"}],"quickstart":{"code":"// transform.ts\nimport type { API, FileInfo, Options } from 'jscodeshift';\n\n/**\n * A simple codemod that transforms `var` declarations to `let` or `const`.\n * It will use `const` if all declarators are simple literals, otherwise `let`.\n */\nexport default function transformer(file: FileInfo, api: API, options: Options): string | null {\n  const j = api.j;\n  const root = j(file.source);\n\n  let changed = false;\n\n  root\n    .find(j.VariableDeclaration, { kind: 'var' })\n    .forEach((path) => {\n      const declarations = path.node.declarations;\n      // A simplistic check to determine if all declarations are immutable literals\n      const allAreConstants = declarations.every(decl =>\n        j.match(decl, { id: j.Identifier, init: j.Literal }) && decl.init !== null\n      );\n\n      if (allAreConstants) {\n        path.node.kind = 'const';\n      } else {\n        path.node.kind = 'let';\n      }\n      changed = true;\n    });\n\n  // Only return the source if changes were made, otherwise return null\n  return changed ? root.toSource() : null;\n}\n\n// To run this codemod on a file named `my-code.js`:\n// 1. Save the above code as `transform.ts`.\n// 2. Ensure `jscodeshift` is installed globally or locally.\n//    `npm install -g jscodeshift`\n// 3. Execute the codemod:\n//    `jscodeshift -t ./transform.ts ./my-code.js --parser=ts`","lang":"typescript","description":"This TypeScript quickstart demonstrates a basic codemod that updates `var` declarations to `let` or `const` based on a simplistic immutability check, then shows how to execute it via the `jscodeshift` CLI."},"warnings":[{"fix":"Upgrade your Node.js environment to version 16 or newer. Use `nvm install 16 && nvm use 16` or similar version management tools.","message":"jscodeshift v17.0.0 and above explicitly require Node.js version 16 or higher. Earlier versions of Node.js are no longer supported.","severity":"breaking","affected_versions":">=17.0.0"},{"fix":"Review the changelog for any specific breaking changes (e.g., Node.js version requirement) beyond the version number itself when upgrading from pre-v17 versions.","message":"The package underwent a significant major version bump from `0.x.x` to `17.0.0`. This jump was a deliberate choice to reflect the project's maturity after nine years, similar to how React transitioned from v0.14 to v15.0, rather than a traditional v1.0.0 release. While the core API largely remained stable, this indicates a new major release branch.","severity":"breaking","affected_versions":"=17.0.0"},{"fix":"Immediately upgrade `jscodeshift` to version `0.13.1` or higher, which replaced `colors` with `chalk`, mitigating the vulnerability.","message":"Versions of `jscodeshift` up to `0.13.0` depended on the `colors` package, which was subject to a critical security vulnerability (supply chain attack) in version `1.4.1`.","severity":"breaking","affected_versions":"<=0.13.0"},{"fix":"Always specify the appropriate parser using the `--parser` CLI option (e.g., `--parser=ts` for TypeScript, `--parser=tsx` for TSX/JSX, `--parser=flow` for Flow). For custom Babel/Flow configurations, use `--parser-config` pointing to a JSON file.","message":"Incorrect or missing parser configuration is a common source of errors when running codemods, especially with TypeScript or JSX files.","severity":"gotcha","affected_versions":"*"},{"fix":"If a strict code style or reformatting is required after running a codemod, consider integrating a separate formatting step (e.g., Prettier or ESLint with `--fix`) into your workflow after the codemod execution.","message":"jscodeshift, via `recast`, prioritizes preserving the original code's style, including formatting, comments, and whitespace. While beneficial, this means it will not automatically reformat your code to a new style guide or apply a linter's autofixes.","severity":"gotcha","affected_versions":"*"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Specify the correct parser via the CLI, for example: `jscodeshift -t transform.js my-file.ts --parser=ts` or `--parser=tsx` for JSX/TSX. Use `--parser-config` for custom Babel/Flow configurations.","cause":"The jscodeshift runner failed to parse the source file, typically due to an incorrect or missing parser setting for the file's language features (e.g., TypeScript, JSX).","error":"Error: SyntaxError: Unknown word (1:0) (or similar parser error like Unexpected token)"},{"fix":"Ensure your `export default function transformer(...)` always returns `root.toSource()` after modifications, or `null` if the file should not be changed.","cause":"The default exported transform function in your codemod file did not return either the modified source code (as a string) or `null` (if no changes were made).","error":"Error: The transform function must return a string or null."},{"fix":"Verify the exact import path. Ensure `jscodeshift` is installed and the subpath `jscodeshift/testUtils` is correctly resolved by your module resolver. This typically occurs in test files.","cause":"An attempt was made to import utilities from `jscodeshift/testUtils` (or other subpaths) with an incorrect path or when the module is not accessible.","error":"Error: Cannot find module 'jscodeshift/testUtils'"},{"fix":"Access the jscodeshift API through the `api` object provided to your transform function: `export default function transformer(fileInfo, api) { const j = api.j; /* ... */ }`.","cause":"The `j` object, which provides the jscodeshift AST API, was used outside the scope of the transform function where it is passed as `api.j`.","error":"ReferenceError: j is not defined"}],"ecosystem":"npm"}